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