62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
// message.ts
|
||
import { createApp } from 'vue'
|
||
import type { App } from 'vue'
|
||
import { provide, inject } from 'vue' // 新增导入
|
||
import type { InjectionKey } from 'vue'
|
||
|
||
import Message from './Message.vue'
|
||
|
||
interface MessageOptions {
|
||
message: string
|
||
type: 'success' | 'error'
|
||
duration?: number
|
||
}
|
||
|
||
const messageInstances: any[] = [] // 存储多个消息实例,防止重叠
|
||
|
||
const showMessage = (options: MessageOptions) => {
|
||
const app = createApp(Message, {
|
||
...options,
|
||
onClose: () => {
|
||
app.unmount()
|
||
const index = messageInstances.indexOf(app)
|
||
if (index > -1) messageInstances.splice(index, 1)
|
||
container.remove()
|
||
}
|
||
})
|
||
|
||
const container = document.createElement('div')
|
||
document.body.appendChild(container)
|
||
app.mount(container)
|
||
|
||
messageInstances.push(app)
|
||
}
|
||
|
||
// 定义 InjectionKey(TypeScript 类型安全)
|
||
const MessageKey: InjectionKey<{
|
||
success: (message: string, duration?: number) => void
|
||
error: (message: string, duration?: number) => void
|
||
}> = Symbol('message')
|
||
|
||
// 插件安装
|
||
const messagePlugin = {
|
||
install(app: App) {
|
||
const message = {
|
||
success: (message: string, duration?: number) =>
|
||
showMessage({ message, type: 'success', duration }),
|
||
error: (message: string, duration?: number) =>
|
||
showMessage({ message, type: 'error', duration })
|
||
}
|
||
app.provide(MessageKey, message) // 使用 provide 注入
|
||
}
|
||
}
|
||
|
||
// 新增:composable 函数,用于在组件中注入
|
||
export const useMessage = () => {
|
||
const message = inject(MessageKey)
|
||
if (!message) throw new Error('useMessage must be used after messagePlugin is installed')
|
||
return message
|
||
}
|
||
|
||
export default messagePlugin
|