vue修改数据后没有更新新值

110 阅读1分钟

今天在定义一个loading指令的时候发现在update钩子函数进行组件实例数据更改时,发现取到的还是旧值。这是为什么呢?

场景重现

先贴出代码

/**
   * 所在组件的 VNode 更新时调用
   * @param {*} el 
   * @param {*} binding 
   */
  update(el, binding) {
    // 通过对比值的变化判断loading是否显示
    console.log('binding.value==', binding.value) // true
    if (binding.oldValue !== binding.value) {
       // 更改值
       el.instance.visible = binding.value;
    }
    console.log('el.instance.visible==', el.instance.visible) // true
    console.log('el.instance==', el.instance) // {..., visible: false}
  },

通过打印结果看出当前组件实例上的visible属性还是原来的值(false)。这是为什么呢? 因为这个visible属性需要等Dom渲染完毕再更改才能有用。说到这个大家估计都想到了nextTick吧,是的,上述代码写在nextTick回调里面就有用了。

vue的视图更新机制

Vue在更新Dom时是异步执行的。当数据发生变化,Vue将开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新。这种机制是为了避免频繁的Dom操作,减少了页面的重绘和重排次数,从而提高页面的渲染性能。

也就是说当我们更改值的时候视图更新还没完成,此时取到的值还是旧值,当视图更新完成之后,更改组件实例数据,加入数据更新队列,数据更新完毕,然后再渲染视图。

nextTick使用场景

这个操作需要使用随数据改变而改变的Dom结构的时候,这个操作都应该放进Vue.nextTick() 回调函数中。当数据更新了,在Dom中渲染后,会自动执行该函数。

完结~撒花~~~