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

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 })
}
}
}