import { Message } from 'element-ui' import { MessageType, ElMessageComponent, ElMessageOptions } from 'element-ui/types/message' const messageTypes: MessageType[] = ['success', 'warning', 'error', 'info'] interface Config { max: number // 最大显示数 isQueue: boolean // 是否以队列形式存储为展示消息 showNewest: boolean // 是否后添加的消息覆盖前面的消息 } interface IEtMessage { (options: ElMessageOptions): EtMessageClass success: (options: TypedElMessageOptions<'success'>) => EtMessageClass warning: (options: TypedElMessageOptions<'warning'>) => EtMessageClass error: (options: TypedElMessageOptions<'error'>) => EtMessageClass info: (options: TypedElMessageOptions<'info'>) => EtMessageClass setConfig: (config: Config) => void } type TypedElMessageOptions = ({ type: T } & Omit) | string class EtMessageClass { constructor(options: ElMessageOptions) { this.init(options) } private init(options: ElMessageOptions) { const { max, isQueue, showNewest } = EtMessageClass.config if (max > 0 && EtMessageClass.instances.length >= max && showNewest && !isQueue) { this.removeMessages() } if (EtMessageClass.instances.length >= max && isQueue) { // 添加队列元素 EtMessageClass.queue.push(this.saveToQueue(options)) } else if (EtMessageClass.instances.length < max || !max) { this.setMessage(options) } } private close: Function | null = null // 获取消息实例和添加事件监听 private setMessage(options: ElMessageOptions) { const instance: ElMessageComponent = Message(options) this.close = instance.close // 监听消息消失事件,从实例列表移除当前消息实例 instance.$watch('visible', () => { EtMessageClass.instances = EtMessageClass.instances.filter((item: ElMessageComponent) => item !== instance) if (EtMessageClass.config.isQueue && EtMessageClass.queue.length) { const firstInstance = EtMessageClass.queue.shift() if (firstInstance) firstInstance() } }) EtMessageClass.instances.push(instance) } // 移除消息 private removeMessages() { const { instances } = EtMessageClass const { max } = EtMessageClass.config EtMessageClass.instances = instances.filter((instance: ElMessageComponent, index) => { if (index < instances.length - max + 1) { instance && instance.close() return false } return true }) } private saveToQueue(options: ElMessageOptions) { return () => { this.setMessage(options) } } static config: Config = { max: 0, isQueue: false, showNewest: true, } static setConfig(config: Config) { EtMessageClass.config = { ...EtMessageClass.config, ...config } } static instances: ElMessageComponent[] = [] // 消息体实例列表 static queue: Function[] = [] // 未展示数据的消息队列 } const EtMessage: IEtMessage = function (options: ElMessageOptions) { return new EtMessageClass(options) } as any EtMessage.setConfig = (config: Config) => { EtMessageClass.config = { ...EtMessageClass.config, ...config } } messageTypes.forEach((type: MessageType) => { EtMessage[type] = (options: TypedElMessageOptions) => { if (typeof options === 'string') { options = { message: options, type, } } else { options.type = type } return new EtMessageClass(options) } }) export default EtMessage