为啥vue在nexttick之后不更新数据?

Posted

技术标签:

【中文标题】为啥vue在nexttick之后不更新数据?【英文标题】:Why doesn't vue update data after nexttick?为什么vue在nexttick之后不更新数据? 【发布时间】:2018-05-30 02:49:46 【问题描述】:

我正在尝试了解 vuejs 的 nexttick 方法,但我不确定为什么在此示例中的 nexttick 之后没有更新消息..

new Vue(
  el: '#app',
  data: 
    message: 'one'
  ,
  created() 
    this.message = 'two';
    this.$nextTick(() => 
      this.message = 'three';
    );
    this.message = 'four'
  
)

如果我使用

回显它
<div id="app">
  <p> message </p>
</div>

我只看到three。我明白为什么会显示一和二,因为 nexttick() 会快速更改数据,但是为什么没有显示 four 呢?

【问题讨论】:

【参考方案1】:

根据你的问题

但是为什么没有显示四个呢?

这是关于宏任务微任务问题。当你使用 nextTick 时,可能你的浏览器支持 promise,所以 Vue 会使用它来执行你的函数。

而且由于 promise 会被归类为 microtask,所以你的 nextTick 函数实际上是在 UI Render 之前完成的。

setTimeout 属于宏任务,你的函数会在 UI Render 之后的下一个事件循环中完成,你会在短时间内看到“四”!!

DOM 更新不等于 UI 渲染

【讨论】:

【参考方案2】:

当您调用$nextTick() 时,它会安排内部函数在下一个滴答中运行。但是,调用 $nextTick() 的函数将在传递给nextTick() 的函数被调用之前完成。

这是$nextTick()https://vuejs.org/v2/api/#vm-nextTick的官方文档

将回调推迟到下一个 DOM 更新周期后执行。采用 在您更改一些数据以等待 DOM 之后立即执行此操作 更新。这与全局 Vue.nextTick 相同,除了 回调的 this 上下文自动绑定到实例调用 这个方法。

this.message = 'three'; 最后被执行,这就是为什么你总是看到“三个”

您的代码实际上按以下顺序执行:

this.message = 'two';
this.message = 'four'
//then in the next tick of the event loop / DOM update which is likely instantaneous
this.message = 'three';

文件中代码的顺序并不能确定 javascript 引擎实际执行的顺序。

【讨论】:

所以 nexttick 最后运行?如果是这样,为什么我不能在“三”之前看到“四” 因为它是瞬间发生的。太快了,你只看到“三个” 为了证明这一点,将 $nextTick() 替换为 setTimeout() 并使用不同的时间。尝试 5000ms、1000ms、100ms、10ms 和 1ms。 $nextTick() 大致相当于setTimeout(fn, 0)

以上是关于为啥vue在nexttick之后不更新数据?的主要内容,如果未能解决你的问题,请参考以下文章

Vue的dom更新机制 & Vue的nextTick

vue nextTick深入理解-vue性能优化DOM更新时机事件循环机制

vue nexttick的理解和使用场景

Vue.nextTick 的原理和用途

Vue.nextTick(callback)

Vue.nextTick(callback)