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