新增: 全局对话框服务 AppDialog,Promise 风格 appAlert/appConfirm/appPrompt 替代原生弹窗
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/* =====================================================================
|
||||
* 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))
|
||||
}
|
||||
Reference in New Issue
Block a user