@prettyy/ui
Version:
vue2 UI
122 lines (107 loc) • 3.72 kB
JavaScript
import Vue from "vue"
import MessageBox from "./main.vue"
import { isObject } from "@prettyy/utils"
import { isVNode } from "../../../utils/vdom"
const MessageBoxConstructor = Vue.extend(MessageBox)
let instance = null // 定义组件实例
let instances = [] // 定义实例组
let count = 1 // 定义统计次数,便于知道创建多少个实例
const Message = function (options) {
options = options || {}
if (typeof options === 'string' || isVNode(options)) {
options = {
message: options
}
}
if (options.duration && typeof options.duration !== "number") {
// 对于duration数字类型的校验
// 用户乱传递非数字类型参数,就抛错不执行后续代码
throw new Error("Error! duration Must be a numeric type ")
}
if (instance) {
instance.close()
}
let userOnClose = options.onClose
let id = 'message_' + count++ // MyMessage函数调用一次,统计次数加一个
options.onClose = function () {
Message.close(id, userOnClose)
}
instance = new MessageBoxConstructor({
// 实例化一个组件实例
data: options, // data传参数,组件的data接收(即传递配置项)
propsData: {
// propsData传参,
count: count, // 将统计的次数传递给子组件
cutCount: cutCount, // 传递一个函数,当MyMessage消失的时候,通知外界
},
})
instance.id = id
if (isVNode(instance.message)) {
instance.$slots.default = [instance.message]
instance.message = null
}
instance.$mount() // 实例组件挂载
document.body.appendChild(instance.$el) // 把这个组件实例的dom元素,追加到document文档中
let verticalOffset = options.offset || 20
instances.forEach(item => {
verticalOffset += item.$el.offsetHeight + 16
})
instance.verticalOffset = verticalOffset
Vue.nextTick(() => {
instance.isShowMessage = true // 将组件的isShowMyMessage属性值置为true,即让实例出现,即消息出现
})
instances.push(instance)
return instance // MyMessage函数执行一次,就会返回一个加工好的实例对象
}
function cutCount() {
// 当message消失一个
count = count - 1 // 就把外界统计的数量减少一个
let messageBoxDomList = document.querySelectorAll(".messageBox") // 然后选中所有的messageDOM元素
for (let i = 0; i < messageBoxDomList.length; i++) {
// 遍历一下这个DOM伪数组
let dom = messageBoxDomList[i] // 所有的都往上移动60像素
dom.style["top"] = parseInt(dom.style["top"]) - 60 + "px"
}
}
["success", "warning", "info", "error"].forEach(type => {
Message[type] = options => {
if (isObject(options)) {
return Message({
...options,
type,
})
}
return Message({
type,
message: options,
})
}
})
Message.close = function (id, userOnClose) {
let len = instances.length
let index = -1
let removedHeight
for (let i = 0; i < len; i++) {
if (id === instances[i].id) {
removedHeight = instances[i].$el.offsetHeight
index = i
if (typeof userOnClose === 'function') {
userOnClose(instances[i])
}
instances.splice(i, 1)
break
}
}
if (len <= 1 || index === -1 || index > instances.length - 1) return
for (let i = index; i < len - 1 ; i++) {
let dom = instances[i].$el
dom.style['top'] =
parseInt(dom.style['top'], 10) - removedHeight - 16 + 'px'
}
}
Message.closeAll = function() {
for (let i = instances.length - 1; i >= 0; i--) {
instances[i].close()
}
}
export default Message