Usage scenario:
It is required to click on the data to display the pop-up window, click on the data in the pop-up window to display a new pop-up window, and the pop-up window inside can continue to click on the new pop-up window, and the pop-up window can be nested unlimitedly
Why not use el-dialog’s append-to-body?
Reason: Because some pop-up windows are both the parent pop-up window and the bullet window, an error will be reported when using it, and a loop nesting error will be reported
Effect image:
Unlimited clicks and unlimited nesting
Code details:
Step 1: Create a new commonData.js and put it in the utils folder
Encapsulate js method
commonData.js file
import Vue from "vue"; let common = {}; if (window) window. common = common; /** * * The common object places all common methods * common.dialog() is the method to call the pop-up box */ 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 || "OK"} </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 || "Cancel"} </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('The value you want to pass'); }); }, methods: { closeDialog() { this. show = false; }, // Confirm button submit(){ this.$refs.childrenRef.submit('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; } //If the type is not passed or the type is equal to close or cancel, close the popup box directly if (!result.type || result.type == "close" || result.type == "cancel") { this. show = false; } else if (result.type == "sure") { //If type is equal to sure, call the callback function passed by parent this. show = false; if (option. callback) { option. callback(result. data); } } } }, components: { child: option.component } }); return v; }; export default common;
Step 2: Create a vue file
Create a folder testDialog folder Create a folder according to your own needs (this is for my demonstration, you can create it yourself according to your own project)
index.vue file
html part
<template> <div style="width:200px;height:200px;background:#eee;color:#000;" @click="openDialog" class="div" > Click me to open the infinite pop-up tour </div> </template>
js part
<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: "I am a pop-up window 0000000000000", //Title initData: obj, // the passed value type: "addInspection", //Multiple pop-up windows with different requirements can be distinguished by type DialogWidth: "60%", //The width of the pop-up window is 70% by default Dialogtop: "3vh", //The height of the pop-up window from the top is not written as 15vh by default btnShow: { show: true, //Whether to display the button showSubmit: true, //Whether to show the OK button // showSubmitText: "", //Confirm button text replacement (optional, can be written or not, if not written, the default is OK) showCancel: true //whether to show the cancel button // showCancelText: "" //Cancel button text replacement ((not required, can be written or not, if not written, the default is cancel) }, parentClass: "addInspection", //class name component: dialog // component }; common.dialog(option); } } }; </script>
css part
<style> .div { display: flex; align-items: center; cursor: pointer; justify-content: center; position: fixed; left: calc(50% - 100px); top: 30%; } </style>
dialog.vue file
html part
<template> <div class="dialogDiv" @click="openDialog"> I am the pop-up window 000000000000000000 </div> </template>
js part
<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: "I am the pop-up window 1111111111111111111", //title initData: obj, // the passed value type: "addInspection", //Multiple pop-up windows with different requirements can be distinguished by type DialogWidth: "60%", //The width of the pop-up window is 70% by default Dialogtop: "3vh", //The height of the pop-up window from the top is not written as 15vh by default btnShow: { show: true, //Whether to display the button showSubmit: true, //Whether to show the OK button // showSubmitText: "", //Confirm button text replacement (optional, can be written or not, if not written, the default is OK) showCancel: true //whether to show the cancel button // showCancelText: "" //Cancel button text replacement ((not required, can be written or not, if not written, the default is cancel) }, parentClass: "addInspection", //class name component: dialogOne // component }; common.dialog(option); }, submit() { this.$emit("closeDialog"); } } }; </script>
css part
<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; } // You can write your own styles // .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>
The remaining two files can be created by yourself according to this. If you want to loop infinitely, write the pop-up window of the last file to the first one, and you can nest unlimitedly!
It’s not easy to develop, if you like it, please pay attention and like it, thank you!