element-ui中dialog的before-close和close的区别以及执行顺序

之前用element-ui里面的dialog组件的时候,总是在给dialog绑定关闭函数的时候,before-close和close都绑定同一个,然后在里面做一样的事情,当时也没想过有什么区别,然后在里面通过以下手段来进行关闭,好像也能正常使用

js 复制代码
// 二次封装组件
this.$emit("update:visible", false);

// 直接关闭
this.visible = false;

但是从来没有思考过这两个到底有什么区别,后来有一次弄懂了,知道了他们的区别,但今天又用到的时候我发现我又记不清了,于是专门写了这篇文章来帮助自己记忆。

首先我们先看看关于element-ui官方对于这两个东西的解释

Events

Attribute

其中before-close是我们传入的一个属性,而close和closed是绑定的事件。

这里官方文档说得不太清楚,before-close是关闭前的回调,但是只是通过右上角的X或者点击弹窗以外的部分关闭的时候会进行的处理,同时在我们传入的这个函数调用的时候,会接收到一个回调函数,我们将其打印可以得到其内容

打印结果

我们可以看看源码

js 复制代码
hide: function hide(cancel) {
  if (cancel !== false) {
    this.$emit('update:visible', false);
    this.$emit('close');
    this.closed = true;
  }
},

这是element-ui\lib\dialog.js的相关代码

我们可以看到它接收一个参数,然后通过对该参数进行判断来执行相应的操作,当我们传入true的时候,首先会向父组件触发update:visible事件,并且更新父组件的vidible属性为false。

可以看看element-ui官方文档中dialog的相关事例代码

js 复制代码
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose"> 
    <span>这是一段信息</span> 
    <span slot="footer" class="dialog-footer"> 
       <el-button @click="dialogVisible = false">取 消</el-button> 
       <el-button type="primary" @click="dialogVisible = false">确 定</el-button> 
    </span> 
</el-dialog>

这里不理解update:visible是什么操作的可以去了解一下vue2中的.sync标识符

首先是触发了外部组件进行visible的更新,但是如果仅仅是通过更新visible来进行更新是无效的,因为外部并没有通过v-if或者v-show进行绑定,所以我们接下来可以看到dialog组件内部对于visible的监听

js 复制代码
// 这里不知道是什么时候接收了外部声明的visible,看看有没有大佬解惑
watch: {
  visible: function visible(val) {
    var _this = this;
    if (val) {
      this.closed = false;
      this.$emit('open');
      this.$el.addEventListener('scroll', this.updatePopper);
      this.$nextTick(function () {
        _this.$refs.dialog.scrollTop = 0;
      });
      if (this.appendToBody) {
        document.body.appendChild(this.$el);
      }
    } else {
      this.$el.removeEventListener('scroll', this.updatePopper);
      if (!this.closed) this.$emit('close');
      if (this.destroyOnClose) {
        this.$nextTick(function () {
          _this.key++;
        });
      }
    }
  }
},

在第17行可以看到,如果此时弹窗是处于开启状态closed === false时,会触发close事件

但是其实真正触发close事件的位置不是在这,我刚刚也踩坑了,发现是先执行了hide函数中的this.closed = true才执行的上面的这个函数,估计是因为emit或者watch的函数是异步执行的,等我有时间研究之后会专门讲一讲

在hide函数中接下来触发了close事件。那么一个流程就走完啦,你可能会好奇,那closed事件是什么时候执行的,我也好奇,于是我又看了一下,看到了这一段代码

js 复制代码
afterLeave: function afterLeave() {
  this.$emit('closed');
}

大致意思就是在动画结束之后执行,也就是触发了closed,至于它的实现,可以看看关于虚拟节点这块,刚刚瞄了一眼看到了。

所以真正的执行顺序应该是 before-close -> close -> closed

总结:

  1. before-close只有通过右上角的X和点击对话框以外区域来退出对话框的时候会触发
  2. close只有通过修改visible的值来进行弹窗关闭的时候会触发,当然before-close接收到的done函数本身也会触发
  3. 执行顺序:before-close -> close -> closed
  4. 通常情况下只需要绑定close和closed事件就足以满足我们的需求了,before-close如果不调用其中的done的函数的话貌似没有多大差别

如果有不对的,欢迎大佬指出!

相关推荐
wocwin2 个月前
vue+element-ui的列表查询条件/筛选条件太多以下拉选择方式动态添加条件(支持全选、反选、清空)
vue.js·element
小Bk2 个月前
“表单大变身:当ElForm遇上Vue 3,开发效率满级的秘密武器”
前端·element
aiguangyuan3 个月前
Element 页面滚动表头置顶
vue·前端开发·element
伊织code3 个月前
Selenium WebDriver - 网络元素
爬虫·selenium·xpath·element·dom·网络元素·by.name
韩曙亮3 个月前
【Web APIs】DOM 文档对象模型 ④ ( querySelector 函数 | querySelectorAll 函数 | NodeList 对象 )
前端·javascript·element·dom·web apis·queryselector·nodelist
xiaok3 个月前
vue+elementui的layout布局中根据路由生成左侧菜单栏
前端·vue.js·element
Java小卷3 个月前
Vue3+TSX手撸Element Tree升级版
vue.js·vite·element
翼晗3 个月前
element-plus 自定义命名空间 el-config-provider namespace 不起作用,html 的class值改变了,但是样式不对
前端·html·element·element plus
红烧咸咸鱼4 个月前
element table表格行列合并span-method,根据数据动态行列合并
element·span-method·element表格行列合并·表格动态行列合并
码农研究僧4 个月前
详细分析Element中的MessageBox基本知识(附Demo)
vue2·js·element·messagebox