import Vue from 'vue' import SuperToast from '@/components/toast-message' const Toast = { install(Vue, options = {}) { // 安全检测浏览器环境 const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' // 创建安全的DOM操作方法 const safeDOM = { createContainer: () => { if (!isBrowser) return null const container = document.createElement('div') container.className = 'uni-toast-container' document.body.appendChild(container) return container }, removeContainer: (container) => { if (isBrowser && container && container.parentNode) { document.body.removeChild(container) } } } let toastInstance = null let currentContainer = null Vue.prototype.$toast = (options) => { // 处理非浏览器环境 if (!isBrowser) { console.warn('[Toast] 当前环境不支持DOM操作') return { close: () => {}, update: () => {} } } // 清理旧实例 if (toastInstance) { toastInstance.$destroy() safeDOM.removeContainer(currentContainer) } // 创建新实例 currentContainer = safeDOM.createContainer() const config = typeof options === 'string' ? { message: options } : options toastInstance = new Vue({ render: h => h(SuperToast, { props: { ...config, showClose: config.showClose ?? true }, on: { close: () => { setTimeout(() => { toastInstance.$destroy() safeDOM.removeContainer(currentContainer) currentContainer = null }, 300) } } }) }).$mount(currentContainer) // 返回控制器 return { close: () => toastInstance?.$children[0]?.hide(), update: (newOptions) => { if (toastInstance?.$children[0]) { Object.assign(toastInstance.$children[0].$props, newOptions) } } } } // 快捷方法 const types = ['info', 'success', 'warning', 'error', 'loading'] types.forEach(type => { Vue.prototype.$toast[type] = (message, duration = 2000) => { return Vue.prototype.$toast({ type, message, duration }) } }) } } Vue.use(Toast)