67 lines
2.3 KiB
TypeScript
67 lines
2.3 KiB
TypeScript
/* =====================================================================
|
||
* dialog.ts — 全局对话框服务(替代原生 alert/confirm/prompt)
|
||
*
|
||
* Promise 风格:await appConfirm('删除?') → boolean
|
||
* 渲染走 AppDialogHost(主 app 内 Teleport 到 body),
|
||
* App.vue 模板放置 <AppDialogHost /> 即接线,无需手动 mount
|
||
* ===================================================================== */
|
||
import { ref } from 'vue'
|
||
|
||
export interface DialogOptions {
|
||
type: 'alert' | 'confirm' | 'prompt'
|
||
title: string
|
||
message?: string
|
||
/** prompt 默认值 */
|
||
defaultValue?: string
|
||
/** input placeholder */
|
||
placeholder?: string
|
||
/** 确认按钮文案(默认「确定」) */
|
||
okText?: string
|
||
/** 危险操作样式(确认按钮红色) */
|
||
danger?: boolean
|
||
}
|
||
|
||
interface DialogResult { ok: boolean; value: string }
|
||
type Resolver = (r: DialogResult) => void
|
||
|
||
/* ---------- 模块级响应式状态(AppDialogHost 渲染消费) ---------- */
|
||
export const dialogState = {
|
||
open: ref(false),
|
||
options: ref<DialogOptions | null>(null)
|
||
}
|
||
|
||
let resolver: Resolver | null = null
|
||
|
||
/** 由 AppDialogHost 的 close 事件回调 */
|
||
export function resolveDialog(r: DialogResult) {
|
||
dialogState.open.value = false
|
||
dialogState.options.value = null
|
||
if (resolver) { resolver(r); resolver = null }
|
||
}
|
||
|
||
function show(opts: DialogOptions): Promise<DialogResult> {
|
||
return new Promise(resolve => {
|
||
resolver = resolve
|
||
dialogState.options.value = opts
|
||
dialogState.open.value = true
|
||
})
|
||
}
|
||
|
||
/* ---------- 对外 API ---------- */
|
||
|
||
/** 信息提示(替代 alert) */
|
||
export function appAlert(title: string, message?: string) {
|
||
return show({ type: 'alert', title, message })
|
||
}
|
||
|
||
/** 确认(替代 confirm)→ Promise<boolean> */
|
||
export function appConfirm(title: string, message?: string, opts?: { okText?: string; danger?: boolean }) {
|
||
return show({ type: 'confirm', title, message, okText: opts?.okText, danger: opts?.danger }).then(r => r.ok)
|
||
}
|
||
|
||
/** 输入(替代 prompt)→ Promise<string | null>(取消为 null) */
|
||
export function appPrompt(title: string, opts?: { message?: string; defaultValue?: string; placeholder?: string }) {
|
||
return show({ type: 'prompt', title, message: opts?.message, defaultValue: opts?.defaultValue, placeholder: opts?.placeholder })
|
||
.then(r => (r.ok ? r.value : null))
|
||
}
|