105 lines
2.2 KiB
JavaScript
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
|
|
}
|
|
}
|