解决el-dialog弹框多重嵌套的问题。实现最好用的el-dialog

      随着vueJs的广泛使用,Element组件逐渐深入人心。但是在使用element组件的时候,难免会遇到一些问题。本文跟大家分享:如何解决el-dialog弹框的多重嵌套问题,实现最好用的私人dialog,当然‘最’可能有点吹流弊啦,用的好请点赞!。
      使用过el-dialog的小伙伴,应该都发现了:el-dialog不好用。 为什么不好用?
      1.弹框不支持嵌套
       2.多个弹框之间遮罩层会相互影响
      但是在我们实际使用的过程中,又经常会有嵌套弹框的需求。虽然按照饿了么提供的不嵌套解决方式(把弹框都平级堆在一起),再通过事件发送和监听等方式来也能绕开这些问题,但是这样下来你会发现:1.多级弹框调用之间需要发送很多事件,弹框相互调用变得很复杂 2.页面多了很多非业务逻辑控制代码(可读性变差) 3.遮罩层变得越来越黑。 4.弹框的可重用性变得很差 。比如弹框一里面打开弹框二,控制代码却要写到弹框一的父页面,这是不是有种隔墙挠痒的感觉!
      那么怎样的弹框才是合理的呢,废话不多说先放代码

    add(){
            let option = {
                title: '添加项目',
                component: Add,
                _size_: 'small',
                data: {action: 'add'},
                callback(result){
                    this.loadList();
                }
            };
            common.dialog(option);
        }

      上面是打开弹框的代码,有没有感觉很简单。 在任何地方我们只要调用add()方法,就会打开内容为Add组件的弹框。我们只需要指定弹框的基本属性:标题title、内容data、大小size、传值。以及有时关闭弹框需要执行的回调函数(比如刷新列表啥的)。这样不仅实现了弹框和弹框体的解耦,而且完美的解决了:弹框嵌套以及遮罩相互影响问题
下面揭露common.dialog()的神秘面纱,具体代码如下

common.dialog = function (option) {
    //dom为解决弹框嵌套以及弹框相互影响的核心
    var dom = document.createElement('div');
    document.getElementsByTagName('body')[0].appendChild(dom);
    var component = option.component;
    let template = '<div v-if="show"><el-dialog  :title="title" v-model="show" :before-close="handleClose" :size="size" @close="close"><child v-on:callback="callback" :init_data="data"> \
        </child></el-dialog></div>';
    var v = new Vue({
          el: dom,
          data: function () {
              return {
                  title: option.title,
                  size: option._size_ == null ? 'small' : option._size_,
                  modal: true,
                  close_on_press_escape: false,
                  show_close: true,
                  show: true,
                  data: option.data,
                };
            },
          template: template,
          mounted: function () {},
          methods: {
              handleClose(done){
                if (option.close) {
                  option.close();
                }
                done();
              },
              close() {
                if (option.close) {
                  option.close();
                }
              },
              callback(result) {
                if (!result.type || result.type == 'close' || result.type == 'cancel') {
                  this.show = false;
                } else if (result.type == 'sure') {
                  this.show = false;
                  if (option.callback) {
                    option.callback(result.data);
                  }
                }
              },
            },
          components: {
              child: option.component,
            },
        });
    return v;
  };

以上是common.dialog()的核心代码,可以直接使用。需要注意的是:

  1. 弹框内容的组件通过props:[“init_data”]接收option.data里面的值。
  2. 弹框内容组件如果需要调用关闭弹框方法
    1) 只是关闭弹框,不执行回调(相当于点击‘取消’按钮)

    this.$emit(“callback”,{type:'cancel'})
    2)关闭弹框并执行回调(相当于点击’保存’按钮)

    this.$emit(“callback”,{type:'sure',data:val });//其中val回调函数的参数

    3)点击弹框右上侧的X按钮,又想执行回调函数。只需在option里面定义option.close函数即可

    上面是common.dialog()的部分代码,基本解决了el-dialog存在的问题。

    经部分网友建议,现提供完整代码以及使用样例。CommonDialog 样例代码可直接使用

Logo

前往低代码交流专区

更多推荐