vue el-dialog 实现弹窗无限嵌套(点击弹窗弹出新的弹窗,可以一直点击)
·
使用场景:
要求点击数据展示弹窗,弹窗中数据点击显示新的弹窗,里面的弹窗还可以继续点击新的弹窗,可以无限制的嵌套弹窗
为什么不用el-dialog的append-to-body?
原因:因为有些弹窗既是父弹窗又是子弹窗,所以使用的时候会报错,报一个循环嵌套错误
效果图:
可以一直无限制的点击 无限制的嵌套
代码详情:
第一步:新建一个commonData.js 放到utils文件夹下
封装js方法
commonData.js 文件
import Vue from "vue";
let common = {};
if (window) window.common = common;
/**
*
* 该common对象放置所有的共用方法
* common.dialog()是调用弹框的方法
*/
common.dialog = function(option) {
var m = document.createElement("div");
document.getElementsByTagName("body")[0].appendChild(m);
var v = "";
let template = "";
template = `<div class="w680" v-if="show">
<el-dialog
:title="title"
:visible.sync="show"
width="${option.DialogWidth ? option.DialogWidth : "70%"}"
top="${option.Dialogtop ? option.Dialogtop : "15vh"}"
:class="parentClass"
:close-on-click-modal="false"
:close-on-press-escape="false" :before-close="handleClose" @close="close">
<child v-on:callback="callback" ref="childrenRef" @closeDialog="closeDialog">
</child>
<span style="display: flex; justify-content: center; align-items: center" slot="footer" class="dialog-footer" v-if='${
option.btnShow.show
}'>
<el-button size="small" style="padding: 8px 25px;
background: #089d81;
color: #fff;
border: 1px solid #089d81;" v-if='${
option.btnShow.showSubmit
}' @click="submit">
${option.btnShow.showSubmitText || "确 定"}
</el-button>
<el-button size="small" style="padding: 8px 25px;
background: #089d81;
color: #fff;
border: 1px solid #089d81;" @click="show = false" v-if='${
option.btnShow.showCancel
}'>
${option.btnShow.showCancelText || "取 消"}
</el-button>
</span>
</el-dialog>
</div>
`;
v = new Vue({
el: m,
data: function() {
return {
title: option.title,
type: option.type,
style: option.style,
show_close: true,
show: true,
parentClass: option.parentClass,
initData: option.initData,
};
},
template: template,
mounted: function() {
this.$nextTick(() => {
this.$refs.childrenRef.init('你想要传过去的值');
});
},
methods: {
closeDialog() {
this.show = false;
},
// 确定按钮
submit(){
this.$refs.childrenRef.submit('提交')
},
handleClose(done) {
var aa = document.getElementsByClassName("w680")[1];
if (!aa) {
var bb = document.getElementsByClassName("v-modal")[0];
if (bb) {
document.getElementsByTagName("body")[0].removeChild(bb);
}
}
if (option.close) {
option.close();
}
done();
},
close() {
var aa = document.getElementsByClassName("w680")[1];
if (!aa) {
var bb = document.getElementsByClassName("v-modal")[0];
if (bb) {
document.getElementsByTagName("body")[0].removeChild(bb);
}
}
if (option.close) {
option.close();
}
},
callback(result) {
if (option._source != null) {
option.callback.call(option._source, result);
this.show = false;
return;
}
//如果不传type或者type等于close或cancel直接关闭弹框
if (!result.type || result.type == "close" || result.type == "cancel") {
this.show = false;
} else if (result.type == "sure") {
//如果type等于sure则调用parent传递过来的回调函
this.show = false;
if (option.callback) {
option.callback(result.data);
}
}
}
},
components: {
child: option.component
}
});
return v;
};
export default common;
第二步:创建vue文件
创建文件夹 testDialog 文件夹 根据自己需要创建文件夹(这个是我用于演示的,根据自己项目自行创建就可以)
index.vue文件
html部分
<template>
<div
style="width:200px;height:200px;background:#eee;color:#000;"
@click="openDialog"
class="div"
>
点我开启无限弹窗之旅
</div>
</template>
js部分
<script>
import common from "@/utils/commonData.js";
import dialog from "./components/dialog.vue";
export default {
data() {
return {};
},
methods: {
openDialog() {
var obj = {
aa: "1"
};
let option = {
title: "我是弹窗0000000000000", //标题
initData: obj, // 传过去的值
type: "addInspection", //多个不同需求的弹窗可以通过type区分
DialogWidth: "60%", //弹窗宽度 默认不写是70%
Dialogtop: "3vh", //弹窗距离顶部高度 默认不写是15vh
btnShow: {
show: true, //是否展示按钮
showSubmit: true, //是否展示确定按钮
// showSubmitText: "", //确定按钮文字替换(非必填项,可写可不写 不写默认是确定)
showCancel: true //是否展示取消按钮
// showCancelText: "" //取消按钮文字替换((非必填项,可写可不写 不写默认是取消)
},
parentClass: "addInspection", //class名
component: dialog // 组件
};
common.dialog(option);
}
}
};
</script>
css部分
<style>
.div {
display: flex;
align-items: center;
cursor: pointer;
justify-content: center;
position: fixed;
left: calc(50% - 100px);
top: 30%;
}
</style>
dialog.vue 文件
html部分
<template>
<div class="dialogDiv" @click="openDialog">
我是弹窗000000000000000000
</div>
</template>
js部分
<script>
import dialogOne from './dialogOne.vue'
export default {
data() {
return {
property: "value"
};
},
methods: {
init(data, dataOne, dataTwo) {
console.log(data, dataOne, dataTwo);
},
openDialog() {
var obj = {
aa: "1"
};
let option = {
title: "我是弹窗11111111111111111111", //标题
initData: obj, // 传过去的值
type: "addInspection", //多个不同需求的弹窗可以通过type区分
DialogWidth: "60%", //弹窗宽度 默认不写是70%
Dialogtop: "3vh", //弹窗距离顶部高度 默认不写是15vh
btnShow: {
show: true, //是否展示按钮
showSubmit: true, //是否展示确定按钮
// showSubmitText: "", //确定按钮文字替换(非必填项,可写可不写 不写默认是确定)
showCancel: true //是否展示取消按钮
// showCancelText: "" //取消按钮文字替换((非必填项,可写可不写 不写默认是取消)
},
parentClass: "addInspection", //class名
component: dialogOne // 组件
};
common.dialog(option);
},
submit() {
this.$emit("closeDialog");
}
}
};
</script>
css部分
<style lang="scss">
.dialogDiv {
width: 200px;
height: 200px;
background: #000;
color: #fff;
}
.el-dialog__header {
padding: 10px 20px 10px;
background-color: #19a199;
}
.el-dialog__header .el-dialog__title {
font-size: 15px;
color: #ffffff;
font-weight: 700;
}
.el-icon-close:before {
color: #fff;
}
.el-dialog__body {
padding: 10px 20px;
height: 50vh;
}
.el-dialog__headerbtn {
top: 15px;
}
// 可以自己去写样式
// .dialog-footer {
// .el-button {
// padding: 8px 25px !important;
// background: #089d81;
// color: #fff;
// border: 1px solid #089d81;
// }
// }
// .el-dialog__body {
// padding-top: 10px;
// height: 50vh;
// overflow-y: auto;
// }
// .el-dialog__headerbtn .el-dialog__close {
// color: #fff;
// }
</style>
剩下两个文件按照这个自行创建即可 想无限制循环 最后一个文件的弹窗写到第一个 就可以无限制嵌套!
开发不易,喜欢的点个关注,点个赞,谢谢!
更多推荐
已为社区贡献5条内容
所有评论(0)