封装message组件
<template>
<transition name="my-fade" @after-leave="handAfterLeave">
<div :class="['custom-message',`my-message-${type}`]"
v-text="msg" v-show="isShow" :style="`top:${topOffset}px`"></div>
</transition>
</template>
<script>
export default {
name: 'CustomMessage',
data() {
return {
msg: '',
duration: 3000,
isShow:false,
topOffset:20,
onClose:null,
type:'success'
}
},
mounted() {
this.closeMsg()
},
methods: {
// 过度动画结束时销毁和移除当前节点dom
handAfterLeave(){
this.$destroy(true)
this.$el.parentNode.removeChild(this.$el)
},
// 设置定时器 关闭消息
closeMsg() {
this.timer = setTimeout(() => {
this.isShow=false
this.close()
clearTimeout(this.timer)
}, this.duration)
},
// 设置关闭时触发的关闭回调函数
close(){
if(typeof this.onClose==='function'){
this.onClose(this)
}
}
},
}
</script>
<style scoped>
.my-fade-enter, .my-fade-leave-to{
opacity: 0;
transform: translateY(-100%);
}
.custom-message {
position: fixed;
left: 38%;
top: 20px;
/* transform: translateX(-50%); */
border-radius: 5px;
min-width: 380px;
padding: 12px;
font-size: 14px;
font-weight: 500;
transition: all 0.4s ease-in-out;
}
.my-message-info{
color: #909399;
background-color: ##edf2fc;
}
.my-message-success{
color:#67c23a;
background-color: #f0f9eb;
}
.my-message-warning{
color: #e6a23c;
background-color: #fdf6ec;
}
.my-message-error{
color: #f56c6c;
background-color: #fef0f0;
}
</style>
使用vue.extend()进行构造
import Vue from 'vue'
import CustomMessage from '../components/CusMessage.vue'
let MsgConstructor = Vue.extend(CustomMessage) // 生成vc的构造函数
let instant
let instants = []
let seed = 0
const Msg = (options) => {
if (typeof options === 'string') {
options = {
msg: options
}
}
let userOnClose = options.onClose //用户传的关闭时的回调函数
let id = "my_message_" + seed++ // 给每个vc 绑定唯一id
options.onClose = function() { //触发定时器结束关闭消息的回调,在这里可移除数组intstants中关闭的消息
Msg.close(id, userOnClose)
}
instant = new MsgConstructor({ // 构造一个vc实例对象(生成一条消息)
data: options
})
instant.id = id
instant.$mount() //将实例挂到index.html中的body下
document.body.appendChild(instant.$el)
instant.isShow = true //将isShow 属性设置为true(用于过渡动画切换)
let topOffset = options.offset || 20
if (instants.length === 0) {
instant.topOffset = 20
}
instants.forEach(item => topOffset += item.$el.offsetHeight + 16) // 设置style的top值
instant.topOffset = topOffset
instant.$el.style.zIndex = seed
instants.push(instant)
return instant
}
// 四种不同类型的消息
let types = ['info', 'success', 'warning', 'error']
types.forEach(type => {
Msg[type] = (options) => {
if (typeof options === 'object') {
return Msg({
type,
...options
})
}
return Msg({
type,
msg: options
})
}
})
Msg.close = (id, userOnClose) => {
let removeHeight;
try {
instants.forEach((item, index) => {
if (id === item.id) {
// 如果用户设置了回调,就在关闭时执行回调
if (typeof userOnClose === 'function') {
userOnClose(item)
}
removeHeight = item.$el.offsetHeight
instants.splice(index, 1) // 移除当前的实例
throw new Error("终止") //终止当前循环
}
})
} catch (e) {
//TODO handle the exception
}
// 如果只有小于等于一条数据则直接返回
if (instants.length <= 0) return
instants.forEach((item, index) => {
item.$el.style.top = parseInt(item.$el.style.top) - removeHeight - 16 + 'px' //给以后的实例设置top
})
}
export default Msg
引入main.js中并挂在vue原型上
import Msg from './plugin/customMessage'
Vue.prototype.$msg=Msg
使用
htm
<el-button @click="info">info</el-button>
<el-button @click="success">success</el-button>
<el-button @click="warning">warning</el-button>
<el-button @click="error">error</el-button>
js
info() {
this.$msg.info("我是info")
},
success() {
this.$msg.success("我是success")
},
warning() {
this.$msg.warning("我是warning")
},
error() {
this.$msg.error("我是error")
},
效果
![](https://img-blog.csdnimg.cn/img_convert/d3c21928004adc9cc54efa46f6c7e950.gif)