Vue $mount实战之实现消息弹窗组件

2020-06-14 06:09:57易采站长站整理

之前的项目一直在使用

Element-UI
框架,element中的
Notification
Message
组件使用时不需要在html写标签,而是使用js调用。那时就很疑惑,为什么
element ui
使用
this.$notify
this.$message
就可以实现这样的功能?

1、实现消息弹窗组件的几个问题

如何在任何组件中使用this.$message就可以显示消息?
如何将消息的dom节点插入到body中?
同时出现多个消息弹窗时,消息弹窗的z-index如何控制?

2、效果预览

3、代码实现

PMessage.vue


<template>
<transition name="message-fade">
<div class="p-message"
:class="[type, extraClass]"
v-show="show"
@mouseenter="clearTimer"
@mouseleave="startTimer">
<div class="p-message-container">
<i class="p-message-icon" :class="`p-message-icon-${type}`"></i>
<div class="p-message-content">
<slot class="p-message-content">
<div v-html="message"></div>
</slot>
</div>
</div>
</div>
</transition>
</template>
<script>
// 绑定事件
function _addEvent(el, eventName, fn){
if(document.addEventListener){
el.addEventListener(eventName, fn, false);
}else if(window.attachEvent){
el.attactEvent('on' + eventName, fn);
}
};
// 解绑事件
function _offEvent(el, eventName, fn){
if(document.removeEventListener){
el.removeEventListener(eventName, fn, false);
}else if(window.detachEvent){
el.detachEvent('on' + eventName, fn);
}
};
export default {
name: "PMessage",
data(){
return {
type: 'success',
duration: 3000,
extraClass: '',
message: '',
timer: null,
closed: false,
show: false
}
},
methods: {
startTimer(){
if(this.duration > 0){
this.timer = setTimeout(() => {
if(!this.closed){
this.close();
}
}, this.duration);
}
},
clearTimer(){
clearTimeout(this.timer);
},
close(){
this.closed = true;
if(typeof this.onClose === 'function'){
// 调用onClose方法,以从p-message.js中的instances数组中移除当前组件,不移除的话就占空间了
this.onClose();
}
},
// 销毁组件
destroyElement(){
_offEvent(this.$el, 'transitionend', this.destroyElement);