import MessageTemplate from './message-template' import Vue from 'vue' const MessageConstructor = Vue.extend(MessageTemplate) const instances = [] let count = 1 const containers = {} const globalsOptions = {} const Message = function (options) { options = { ...globalsOptions, ...options } let userOnClose = options.onClose const position = options.position || 'top-center' const hasMask = options.hasMask || false const containerKey = position + (hasMask ? '-mask' : '') let containerEl = containers[containerKey] if (!containerEl) { containerEl = containers[containerKey] = document.createElement('div') containerEl.className = [ 'm-message-container', 'is-' + position, hasMask ? 'has-mask' : '' ].filter(function (e) { return !!e }).join(' ') document.body.appendChild(containerEl) } if (options.zIndex) { containerEl.style.zIndex = options.zIndex } const id = count++ options.onClose = function () { Message.close(id, userOnClose) } const instance = new MessageConstructor({ el: document.createElement('div'), data: options }) instance.id = id instance.containerKey = containerKey // for position of bottom-* if (position.indexOf('bottom') === 0 && containerEl.firstChild) { containerEl.insertBefore(instance.$el, containerEl.firstChild) } else { containerEl.appendChild(instance.$el) } // 挂载后再设置显示才有过渡效果 instance.show = true instances.push(instance) return instance } Message.close = function (id, userOnClose) { for (let i = 0, len = instances.length; i < len; i++) { if (id === instances[i].id) { const { containerKey, hasMask } = instances[i] // 响应options.onClose if (typeof userOnClose === 'function') { userOnClose(instances[i]) } instances[i] = null instances.splice(i, 1) // 如果开启遮罩,300ms 后移除容器(不移除白屏时间太长) if (hasMask) { setTimeout(function () { const count = instances.filter(e => e.containerKey === containerKey).length if (count === 0 && containers[containerKey]) { containers[containerKey].remove() containers[containerKey] = null } }, 300) } break } } setTimeout(function () { // 当前没有消息后,移除容器 if (instances.length === 0) { for (let type in containers) { if (containers[type]) { containers[type].remove() containers[type] = null } } } }, 3000) } Message.closeAll = function () { for (let i = instances.length - 1; i >= 0; i--) { instances[i].close() } } // global options Message.globals = { options: globalsOptions } const types = [ 'info', 'success', 'error', 'warning', 'loading' ] types.forEach(type => { Message[type] = function (options) { options = typeof options === 'string' ? { message: options } : options return Message({ ...options, type }) } }) export default Message