- 新增 showDialog({component, props, title,...}) 服务,返回 Promise
- 内容组件 defineExpose({submit}) 校验并返回数据,校验失败对话框不关闭
- <ty-dialog /> 宿主挂 App.vue,统一渲染对话框栈(支持嵌套)
- ty-crud 改用 showDialog 打开表单(移除 ty-form-dialog)
- ty-form 增加 submit();用户管理页重置密码抽成独立组件 + showDialog
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import { markRaw, reactive, type Component } from 'vue'
|
||
|
||
export interface DialogOptions {
|
||
/** 对话框内容组件。 */
|
||
component: Component
|
||
title?: string
|
||
width?: string
|
||
/** 传给内容组件的 props。 */
|
||
props?: Record<string, any>
|
||
confirmText?: string
|
||
cancelText?: string
|
||
/** 是否显示默认 取消/确定 底部(false 时内容组件自带底部)。 */
|
||
showFooter?: boolean
|
||
/** 确认回调,参数为内容组件 submit() 返回的数据。 */
|
||
onConfirm?: (data: any) => void | Promise<void>
|
||
}
|
||
|
||
export interface DialogInstance {
|
||
id: number
|
||
options: DialogOptions
|
||
resolve: (value: any) => void
|
||
}
|
||
|
||
/** 当前打开的对话框栈(由 <ty-dialog /> 宿主渲染)。 */
|
||
export const dialogs = reactive<DialogInstance[]>([])
|
||
|
||
let seq = 0
|
||
|
||
/**
|
||
* 打开一个对话框。返回 Promise:确认时 resolve 内容组件 submit() 返回的数据,
|
||
* 取消/关闭时 resolve null。
|
||
*/
|
||
export function showDialog(options: DialogOptions): Promise<any> {
|
||
return new Promise((resolve) => {
|
||
dialogs.push({
|
||
id: ++seq,
|
||
options: { ...options, component: markRaw(options.component) },
|
||
resolve,
|
||
})
|
||
})
|
||
}
|
||
|
||
/** 关闭指定对话框并 resolve。 */
|
||
export function closeDialog(id: number, result?: any): void {
|
||
const idx = dialogs.findIndex((d) => d.id === id)
|
||
if (idx >= 0) {
|
||
const [dialog] = dialogs.splice(idx, 1)
|
||
dialog.resolve(result)
|
||
}
|
||
}
|