73 lines
1.4 KiB
JavaScript
73 lines
1.4 KiB
JavaScript
// composables/useToast.js
|
||
import { h, render } from 'vue'
|
||
import Toast from '@/components/Toast.vue'
|
||
|
||
let toastInstance = null
|
||
let container = null
|
||
|
||
function createToastContainer() {
|
||
if (!container) {
|
||
container = document.createElement('div')
|
||
container.id = 'toast-container'
|
||
document.body.appendChild(container)
|
||
}
|
||
return container
|
||
}
|
||
|
||
function showToast(options) {
|
||
if (!process.client) return
|
||
|
||
const {
|
||
type = 'info',
|
||
title = '',
|
||
message = '',
|
||
url = '',
|
||
duration = 3000,
|
||
showClose = true
|
||
} = options
|
||
|
||
// 如果已有 toast,先关闭
|
||
if (toastInstance) {
|
||
toastInstance.close()
|
||
}
|
||
|
||
const toastContainer = createToastContainer()
|
||
|
||
// 创建 Toast 组件实例
|
||
const vnode = h(Toast, {
|
||
type,
|
||
title,
|
||
message,
|
||
url,
|
||
duration,
|
||
showClose,
|
||
onClose: () => {
|
||
if (toastInstance) {
|
||
render(null, toastContainer)
|
||
toastInstance = null
|
||
}
|
||
}
|
||
})
|
||
|
||
render(vnode, toastContainer)
|
||
toastInstance = vnode.component.exposed
|
||
|
||
// 显示 toast
|
||
toastInstance.show()
|
||
}
|
||
|
||
export function useToast() {
|
||
return {
|
||
success: (title, message = '', url = '') => {
|
||
showToast({ type: 'success', title, message, url })
|
||
},
|
||
error: (title, message = '', url = '') => {
|
||
showToast({ type: 'error', title, message, url })
|
||
},
|
||
info: (title, message = '', url = '') => {
|
||
showToast({ type: 'info', title, message, url })
|
||
},
|
||
show: showToast
|
||
}
|
||
}
|