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