Vue 自定义一个全局弹框组件
前文:其实element ui有提供this.$mesage和this.$notify弹框组件可供使用,但是我们的ui设计的样式以及布局还是不完全一样的,为了达到100%的呈现效果,所以自己写了一个全局组件,然后在页面上直接this.$popupMessage()调用首先,需要创建一个vue文件来写我们的弹框样式,新建PopupMessage.vue<template><div
前文:其实element ui有提供this.$mesage和this.$notify弹框组件可供使用,但是我们的ui设计的样式以及布局还是不完全一样的,为了达到100%的呈现效果,所以自己写了一个全局组件,然后在页面上直接this.$popupMessage()调用
首先,需要创建一个vue文件来写我们的弹框样式,新建PopupMessage.vue
<template>
<div class="popup-message warning">
<div class="pop-view">
<span class="pop-title">标头</span>
<p class="pop-content">内容</p>
<div class="pop-btn">
<el-button type="primary" class="save" @click="closeMessage">确定</el-button>
</div>
<i class="delete" @click="closeMessage"></i>
</div>
</div>
</template>
methods: {
getParams(options) {
this.callBack = options.callBack;
// options就是调用this.$popupMessage传过来的参数和方法
}
}
需要我们在main.js里面给Vue添加$popupMessage方法,使用$mount()给组件手动挂载参数,然后将组件插入页面中
提示:$mount()里面如果没有参数,说明组件只是渲染了但是还没挂载到页面
import PopupMessage from "@/components/PopupMessage.vue" // 将组件引入
let popupMessage = null
let init = () => {
// 用Vue.extend 创建组件的模板(构造函数)
let messageConstructor = Vue.extend(PopupMessage);
// 实例化组件,构造函数可以传参 data, method
popupMessage = new messageConstructor({});
// 挂载组件到页面上
popupMessage.$mount();
document.body.appendChild(popupMessage.$el)
}
let caller = (options) => {
init(options);
// getParams是在组件里定义的方法,获取传过来的参数和方法
popupMessage.getParams(options);
}
Vue.prototype.$popupMessage = caller;
然后我们就可以在想要调用的地方直接使用this.$popupMessage()用啦
以下是我实际项目的代码和运行结果效果图,有需要的可以参考
popupMessage.vue
<template>
<div class="popup-message warning" :class="type">
<div class="pop-view">
<span class="pop-title">{{ this.tips || ''}}</span>
<p class="pop-content" v-if="this.msg">{{ this.msg }}</p>
<div class="pop-btn" v-if="button">
<el-button type="primary" class="save" @click="closeMessage">确定</el-button>
</div>
<i class="delete" @click="closeMessage"></i>
</div>
</div>
</template>
<script>
export default {
name: 'PopupMessage',
// props: ["timeVisible", "cfgData", "timeTitle"],
data() {
return {
//
callback: null,
tips: '',
type: '',
msg: '',
button: false,
duration: 0,
};
},
computed: {
//
},
methods: {
getParams(options) {
this.callBack = options.callBack;
this.type = options.type || ''
this.tips = options.tips || ''
this.msg = options.msg || ''
this.button = options.button || false
this.duration = options.duration || 0
this.changePosition()
if(this.duration > 0){
window.setTimeout(() => {
this.$destroy(true)
if(this.$el.parentNode){ // 当前节点是否已经被手动移除
this.$el.parentNode.removeChild(this.$el)
}
this.changePosition()
}, this.duration)
}
},
changePosition() {
let doc = document.body.getElementsByClassName('popup-message')
let sum = 0;
for(let i=0; i< doc.length; i++){
this.$nextTick(() => {
if(i>0){
sum = sum + document.body.getElementsByClassName('popup-message')[i-1].clientHeight + 5
document.body.getElementsByClassName('popup-message')[i].style = `top: ${sum}px`
}else{
document.body.getElementsByClassName('popup-message')[i].style = `top: 0`
}
})
}
},
closeMessage(){
this.$destroy(true)
this.$el.parentNode.removeChild(this.$el)
this.changePosition()
}
},
mounted() {
},
};
</script>
<style lang="scss" scoped>
.popup-message {
font-family: "Source Han Sans Regular";
color: #333333;
position: fixed;
top: 0;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 500px;
height: fit-content;
border-radius: 8px;
background: #FFFFFF;
border: 1px solid #C2C2C2;
z-index: 9999;
.pop-view{
position: relative;
min-height: 120px;
height: auto;
padding-bottom: 13px;
.pop-title{
display: block;
font-size: 18px;
font-weight: 500;
padding: 13px 52px 9px 52px;
position: relative;
&::before{
position: absolute;
content: '';
background-image: url('~@/assets/popup/warning.png');
width: 22px;
height: 22px;
left: 20px;
}
}
.pop-content{
font-weight: 400;
font-size: 14px;
padding: 0 52px 5px 52px;
}
.pop-btn{
display: flex;
justify-content: flex-end;
.save{
margin-right: 20px;
}
}
.delete{
position: absolute;
content: '';
background-image: url('~@/assets/popup/delete.png');
width: 22px;
height: 22px;
top: 18px;
right: 23px;
}
}
}
.success{
background: #F6FFED;
border: 1px solid #73D13D;
color: #73D13D;
.pop-view{
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.pop-view>.pop-title{
&::before{
background-image: url('~@/assets/popup/success.png');
}
}
}
.error{
background: #FFF1F0;
border: 1px solid #FF7875;
// color: #FF7875;
.pop-view>.pop-title{
&::before{
background-image: url('~@/assets/popup/error.png');
}
}
}
</style>
main.js
import PopupMessage from '@/components/PopupMessage.vue';
let popupMessage = null;
let init = () => {
let messageConstructor = Vue.extend(PopupMessage);
// 构造函数可以传参,data,method
popupMessage = new messageConstructor({});
popupMessage.$mount();
document.body.appendChild(popupMessage.$el);
}
let caller = (options) => {
init(options);
// PopupMessage.vue 中使用getParams接收调用时传入的参数。 type: image等
popupMessage.getParams(options);
}
页面使用
this.$popupMessage({
tips: "title", // 标题
msg: 'content', // 内容
type: 'type', // 弹框类型
button: true, // 确定按钮
duration: 3000, // 延迟时间
callBack: (data) => {
// ...
}
})
效果图
更多推荐
所有评论(0)