VUE中this.$nextTick()的使用

需求描述

在进行系统优化时,需要将原来手动输入的列表排序(序号不能重复),修改其中一行的排序number后,列表按新的排序重新渲染一遍

问题描述

使用el-input-number组件进行数字输入,使用@change事件监听输入框数字变化,当数据变化时,对列表数据重新进行排序,排序不成功

产生原因

数据变化后,页面同时开始渲染和触发change事件里的逻辑,此时,change事件逻辑里使用的数据有可能是修改前的,也可能是修改后的,数据不稳定,所以排序会出现乱序的现象

解决办法

在change事件的逻辑使用this.$nextTick()进行包裹

 handleChange() {
      this.$nextTick(function () {
        let temp = JSON.parse(JSON.stringify(this.tableData));
        temp.sort(function(a, b) {
          return a.orderNo - b.orderNo;
        });
        temp.forEach((item, index) => {
          item.orderNo = index + 1;
        });
        this.tableData = temp;
      });
    },

知识点分析

$nextTick()用法

在下次 DOM 更新循环结束之后执行延迟回调

VUE的异步更新队列(JS运行机制 、 事件循环)

Vue 在观察到数据变化时并不是直接更新 DOM,而是开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。然后,在下一个事件循环 tick 中,Vue 刷新队列并执行实际(已去重的)工作。
所以如果用 for 循环来动态改变数据100次,其实它只会应用最后一次改变,如果没有这种机制,DOM就要重绘100次,是一个很大的开销,损耗性能。

    //改变数据
vm.message = 'changed'
 
//想要立即使用更新后的DOM。这样不行,因为设置message后DOM还没有更新
console.log(vm.$el.textContent) // 并不会得到'changed'
 
//这样可以,nextTick里面的代码会在DOM更新后执行
Vue.nextTick(function(){
    console.log(vm.$el.textContent) //可以得到'changed'
})
posted @ 2020-05-18 21:15  laviniatu  阅读(292)  评论(0编辑  收藏  举报