2025-12-04 10:04:21 +08:00

105 lines
2.2 KiB
JavaScript

// composables/useConfirm.js
import { h, render } from 'vue'
import ConfirmDialog from '@/components/ConfirmDialog.vue'
let dialogInstance = null
let container = null
function createDialogContainer() {
if (!container) {
container = document.createElement('div')
container.id = 'confirm-dialog-container'
document.body.appendChild(container)
}
return container
}
function showConfirm(options) {
if (!process.client) return Promise.reject(new Error('Not in client'))
return new Promise((resolve, reject) => {
const {
type = 'warning',
title = '确认操作',
message = '',
confirmText = '确定',
cancelText = '取消',
closeOnClickOverlay = true
} = options
// 如果已有对话框,先关闭
if (dialogInstance) {
dialogInstance.close()
}
const dialogContainer = createDialogContainer()
// 创建 ConfirmDialog 组件实例
const vnode = h(ConfirmDialog, {
type,
title,
message,
confirmText,
cancelText,
closeOnClickOverlay,
onConfirm: () => {
resolve(true)
cleanup()
},
onCancel: () => {
resolve(false)
cleanup()
},
onClose: () => {
cleanup()
}
})
render(vnode, dialogContainer)
dialogInstance = vnode.component.exposed
// 显示对话框
dialogInstance.show()
function cleanup() {
if (dialogInstance) {
setTimeout(() => {
render(null, dialogContainer)
dialogInstance = null
}, 300) // 等待动画结束
}
}
})
}
export function useConfirm() {
return {
confirm: (title, message = '', options = {}) => {
return showConfirm({
type: 'warning',
title,
message,
...options
})
},
danger: (title, message = '', options = {}) => {
return showConfirm({
type: 'danger',
title,
message,
confirmText: '删除',
...options
})
},
info: (title, message = '', options = {}) => {
return showConfirm({
type: 'info',
title,
message,
...options
})
},
show: showConfirm
}
}