3
votes

I am trying to learn about vuejs nexttick methods and I'm not sure why message isn't being updated after nexttick in this example..

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

If I echo it using

<div id="app">
  <p>{{ message }}</p>
</div>

I only see three. I understand after why one and two are showng because nexttick() changes the data rapidly, but why is four not shown instead?

2

2 Answers

3
votes

When you call $nextTick(), it schedules the inner function to be run in the next tick. However, the function that is calling $nextTick() will complete before the function passed into nextTick() will be called.

Here is the offical documenation for $nextTick() https://vuejs.org/v2/api/#vm-nextTick

Defer the callback to be executed after the next DOM update cycle. Use it immediately after you’ve changed some data to wait for the DOM update. This is the same as the global Vue.nextTick, except that the callback’s this context is automatically bound to the instance calling this method.

this.message = 'three'; is getting executed last, which is why you always see "three"

Your code actually executes in the following order:

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

The order of your code in your file does not determine the order in which it is actually executed by the javascript engine.

1
votes

According to your question about

but why is four not shown instead?

it's about macrotask microtask problem. when you use nextTick, maybe your browser support promise, so Vue will use it to execute your function.

And because of promise will be classified to microtask, your nextTick function actually done before UI Render.

setTimeout is classified to macrotask, your function will be done at the next event loop after UI Render, you will see 'four' for a short time!!

DOM updated not equal to UI Render