我们使用element-ui时会发现message-box消息提示是直接通过this.$message引用,而不是每次用的时候都先import然后注册组件。其实它的实现原理也很简单,主要就是使用了Vue.extend方法;接下来我们自己实现一个简单的message-box。
先看效果图:
1、message-box.vue
<template>
<transition name="confirm-fade">
<div class="confirm" v-show="showFlag">
<div class="confirm-wrapper">
<div class="confirm-content">
<p class="text">{{title}}</p>
<div class="operate" @click.stop>
<div class="operate-btn left" @click="cancel">{{cancelBtnText}}</div>
<div class="operate-btn" @click="confirm">{{confirmBtnText}}</div>
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
export default {
data() {
return {
showFlag: false,
title: "默认内容",
confirmBtnText: "确定",
cancelBtnText: "取消"
};
},
methods: {
show() {
this.showFlag = true
return new Promise((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
},
cancel() {
this.reject('cancel')
this.hide()
},
confirm() {
this.resolve('confirm')
this.hide()
},
hide() {
this.showFlag = false
document.body.removeChild(this.$el)
this.$destroy()
}
}
};
</script>
<style scoped lang="scss">
.confirm {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 998;
background-color: rgba(0, 0, 0, 0.3);
&.confirm-fade-enter-active {
animation: confirm-fadein 0.3s;
.confirm-content {
animation: confirm-zoom 0.3s;
}
}
.confirm-wrapper {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 999;
.confirm-content {
width: 270px;
border-radius: 13px;
background: #333;
.text {
padding: 19px 15px;
line-height: 22px;
text-align: center;
font-size: 18px;
color: rgba(255, 255, 255, 0.5);
}
.operate {
display: flex;
align-items: center;
text-align: center;
font-size: 18px;
.operate-btn {
flex: 1;
line-height: 22px;
padding: 10px 0;
border-top: 1px solid rgba(0, 0, 0, 0.3);
color: rgba(255, 255, 255, 0.3);
&.left {
border-right: 1px solid rgba(0, 0, 0, 0.3);
}
}
}
}
}
}
@keyframes confirm-fadein {
0% {opacity: 0;}
100% {opacity: 1;}
}
@keyframes confirm-zoom {
0% {transform: scale(0);}
50% {transform: scale(1.1);}
100% {transform: scale(1);}
}
</style>
2、message-box.js
import component from './index.vue'
function install (Vue) {
Vue.prototype.$message = (options => {
let Constructor = Vue.extend(component)
let instance = new Constructor()
instance.$mount()
document.body.appendChild(instance.$el)
Object.assign(instance, options)
return instance.show()
})
}
export default install
3、main.js引入组件
import messageBox from './components/message-box/index.js'
Vue.use(messageBox)
4、代码中调用
this.$message({
title: 'vue大法好!'
}).then(confirm => {
console.log(confirm)
}).catch(cancel => {
console.log(cancel)
})
原文链接:https://huolihua.cn/#/article-detail/rsycy352oi800000
文章借鉴:https://juejin.cn/post/6844903946088103949