Files
gloabl_award_front/src/components/Message/message.ts

62 lines
1.6 KiB
TypeScript
Raw Normal View History

2026-03-09 17:25:28 +08:00
// 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)
}
// 定义 InjectionKeyTypeScript 类型安全)
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