z8018
8 天以前 d5317aef1dbb595923af02ede8bfa33ba37d6eb6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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)