You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
|
1 month ago
|
import { createApp, h } from 'vue'
|
||
|
|
import ToastComponent from '@/components/Toast.vue'
|
||
|
|
|
||
|
|
const toastContainers = new Map<string, { instance: ReturnType<typeof createApp>, container: HTMLDivElement }>()
|
||
|
|
|
||
|
|
export const useCusToast = () => {
|
||
|
|
const showToast = (options: { type: string, message: string, duration?: number }) => {
|
||
|
|
const id = `toast-${Date.now()}`
|
||
|
|
const duration = options.duration || 3000
|
||
|
|
|
||
|
|
const container = document.createElement('div')
|
||
|
|
document.body.appendChild(container)
|
||
|
|
|
||
|
|
const toastApp = createApp({
|
||
|
|
setup() {
|
||
|
|
return () => h(ToastComponent, {
|
||
|
|
...options,
|
||
|
|
onClose: () => {
|
||
|
|
closeToast(id)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
toastApp.mount(container)
|
||
|
|
|
||
|
|
toastContainers.set(id, {
|
||
|
|
instance: toastApp,
|
||
|
|
container
|
||
|
|
})
|
||
|
|
|
||
|
|
// 自动关闭
|
||
|
|
setTimeout(() => {
|
||
|
|
closeToast(id)
|
||
|
|
}, duration)
|
||
|
|
}
|
||
|
|
|
||
|
|
const closeToast = (id: string) => {
|
||
|
|
const toast = toastContainers.get(id)
|
||
|
|
if (toast) {
|
||
|
|
toast.instance.unmount()
|
||
|
|
document.body.removeChild(toast.container)
|
||
|
|
toastContainers.delete(id)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
toast: {
|
||
|
|
info: (message: string, duration?: number) => showToast({ type: 'info', message, duration }),
|
||
|
|
success: (message: string, duration?: number) => showToast({ type: 'success', message, duration }),
|
||
|
|
warning: (message: string, duration?: number) => showToast({ type: 'warning', message, duration }),
|
||
|
|
error: (message: string, duration?: number) => showToast({ type: 'error', message, duration })
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|