import Vue from 'vue'; import Message from './render/message.vue'; import Notification from './render/notification.vue'; const PopupManager = require('element-ui/src/utils/popup').PopupManager; const isVNode = require('element-ui/src/utils/vdom').isVNode; let MessageConstructor = Vue.extend(Message); let NotificationConstructor = Vue.extend(Notification); import { NoticeOptions } from './interface/notice-options'; /** * 提示信息 * * @export * @class AppNotice */ export class AppNotice { /** * 唯一实例 * * @private * @static * @memberof AppNotice */ private static readonly instance = new AppNotice(); /** * 获取唯一实例 * * @static * @return {*} {AppNotice} * @memberof AppNotice */ public static getInstance(): AppNotice { return AppNotice.instance; } /** * 当前存在的实例集合 * * @private * @type {*} * @memberof AppNotice */ private instances: any = []; /** * 计数标识 * * @private * @memberof AppNotice */ private seed = 1; /** * 打开提示信息 * * @param {*} options * @return {*} * @memberof AppNotice */ public open(options: NoticeOptions) { if (!options) { return; } this.handleDefault(options); const isMessage = options.position == 'top'; let id = 'notice_' + this.seed++; let userOnClose = options.onClose; options.onClose = () => { this.close(id, userOnClose); }; let instance: any; if (isMessage) { instance = new MessageConstructor({ data: options, }); } else { instance = new NotificationConstructor({ data: options, }); } instance.id = id; // message为节点时的处理 if (isVNode(instance.message)) { instance.$slots.default = [instance.message]; instance.message = null; } instance.$mount(); document.body.appendChild(instance.$el); // 计算偏移量 let verticalOffset = options.offset || 16; this.instances .filter((item: any) => item.position === options.position) .forEach((item: any) => { verticalOffset += item.$el.offsetHeight + 16; }); instance.verticalOffset = verticalOffset; instance.visible = true; instance.$el.style.zIndex = PopupManager.nextZIndex(); this.instances.push(instance); return instance; } /** * 处理options的默认值 * * @private * @param {*} options * @memberof AppNotice */ private handleDefault(options: any) { if (!options.position) { options.position = 'top'; } else { // 标题没有时显示默认标题 if (!options.title) { switch (options.type) { case 'error': options.title = '错误'; break; case 'success': options.title = '成功'; break; case 'warning': options.title = '警告'; break; default: options.title = '消息'; } } } } /** * 单个实例的公共关闭方法 * * @param {*} id * @param {*} userOnClose 用户自定义回调 * @memberof AppNotice */ public close(id: any, userOnClose: any) { let len = this.instances.length; let index = -1; const instance = this.instances.find((instance: any, i: number) => { if (instance.id === id) { index = i; return true; } return false; }); if (!instance) return; // 调用用户自定义关闭回调 if (typeof userOnClose === 'function') { userOnClose(instance); } this.instances.splice(index, 1); if (len <= 1) return; const position = instance.position; const removedHeight = instance.$el.offsetHeight; for (let i = index; i < len - 1; i++) { if (this.instances[i].position === position) { this.instances[i].$el.style[instance.verticalProperty] = parseInt(this.instances[i].$el.style[instance.verticalProperty], 10) - removedHeight - 16 + 'px'; } } } /** * 关闭所有实例 * * @memberof AppNotice */ public closeAll() { for (let i = this.instances.length - 1; i >= 0; i--) { this.instances[i].close(); } } }