关于Element对话框组件Dialog在使用时的一些问题及解决办法

Element对话框组件Dialog在我们的实际项目开发中可以说是一个使用频率较高的组件,它能为我们展示提示的功能,如:业务模块提交前展示我们曾经输入或选择过的业务信息,或者展示列表信息中某项业务的具体列表数据;也能为我们展示一些表单操作的需求,如:个人信息的添加或编辑等。Dialog组件使用起来也很方便,稍微封装一下就是一个公共的对话框组件,显示或隐藏也可以通过它的visible属性来设置即可。

这是官网上给出的一个Dialog组件的基本用法:

<el-button type="text" @click="dialogVisible = true">点击打开 Dialog</el-button>

<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>

<script>
  export default {
    data() {
      return {
        dialogVisible: false
      };
    },
    methods: {
      handleClose(done) {
        this.$confirm('确认关闭?')
          .then(_ => {
            done();
          })
          .catch(_ => {});
      }
    }
  };
</script>

使用起来若是只单纯的用作提示或展示信息,那再好不过,只是有时我们会用它来操作个人信息和业务信息的添加或编辑,这就会出现一些Element官网没有给出解决办法的问题亦或这样那样使用可能会导致的某种问题,比如我们在Dialog组件中加入了有正则验证的表单,就可能会出现获取不到表单DOM以及表单的正则验证一会儿有效,一会儿又失效的情况,以及在弹出对话框后,其里边的表单输入框明明有值,却提示不能为空的正则验证,不知道的同学,还以为是Element的坑呢,其实不是。


△ 在弹出编辑的对话框后带出活动名称的值,却出现了“请输入活动名称”的正则验证提示

那么,是什么导致这样的问题的出现呢?

很简单,是因为DOM元素还没有渲染完成导致的,也就是说,当Dialog对话框弹出后,这个对话框及其里边的DOM元素是有一个渲染的过程的,这个过程可能我们肉眼很难察觉到。大概的意思跟Vue的生命周期函数created和mounted类似,在Vue的生命周期函数created中,我们是拿不到页面的DOM元素的,因为此时DOM元素并未进行任何渲染,但在mounted函数中就不一样了,该函数执行时所有的DOM元素挂载和渲染都已完成,此时在该函数中进行任何DOM操作都不会有问题 。

话是这么说,可在调用Dialog对话框的页面中如何拿到其DOM元素呢,之前说的在对话框中嵌套的表单的正则验证会失效的问题改如何解决呢?或者明明表单有值,却正则验证提示“不能为空”呢?

此时,我们就要隆重有请Vue的杀手锏'nextTick'出场了。

Vue官方文档的说法是:在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。详细一点的解释是:

Vue 异步执行DOM更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个watcher被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和DOM操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0)代替。

巴拉巴拉说了那么多,其实就是在弹出Dialog对话框时执行nextTick就可以了,然后在nextTick的函数中执行DOM操作或者给表单赋值就不会出现上述的问题了。

还有一点需要注意,阿拉在点击编辑按钮弹出对话框并给对话框中的表单赋值后,如果我们在进行了一系列的操作如提交修改后的信息并关闭了对话框或者直接点击取消按钮关闭了对话框,那么在关闭时最好再执行一下Element提供的表单的重置方法resetFields(),防止它又出现什么幺蛾子!

posted @ 2019-10-29 14:40  豫见陈公子  阅读(6675)  评论(0编辑  收藏  举报