2
votes

In my opinion,the process should be: DataChange --> DOM-Rerender --> Callback function passed to $nextTick execute. right? but in the simple example below,I can't figure it out

<div id='app'>
  {{msg}}
</div>

  let app = new Vue({
  el:'#app',
  data:{
    msg:'message'
  },
  mounted(){
    this.$nextTick(()=>{
      this.message = 'NEW MESSAGE'
    })
  }
})

Idon't know why the function execute(the message become 'NEW MESSAGE'),'cause I didn't change any data, I thought I must change data like ' this.someDataProperty = foo ' so the callback passed to $nextTick could execute?

and I read docs about vm.$nextTick,it says callback passed to the nextTick function will be executed after the next DOM update.but what is next DOM update? is it about time or browser repaint? what is next DOM update if the datachange may occur anytime?like this:

//...
mounted(){
 this.msg = 'foo'
 axios.get('//bar.com').then(response=>{
   this.msg = response.msg
 })
 axios.get('//baz.com').then(response=>{
   this.msg = response.msg
 })
 this.$nextTick(function(){
   console.log(document.querySelector('#app').innerHTML)
 })
}

could someone tell me when exactly the next DOM update?

1

1 Answers

4
votes

Your understanding of this.$nextTick is slightly incorrect. When you pass a callback to $nextTick, Vue will wait for the DOM to update (because of any outstanding data changes) before executing the callback. But, if there are no outstanding data changes, and no DOM update, the callback will just get immediately called. The documentation is admittedly unclear about this behavior, but you can see the logic in the source code.

It seems like you want to change a value when the DOM updates. To do that, you can use the updated lifecycle hook.

Here's an example, where changing the bound value of the input field will update the DOM and thus cause the updated hook to fire, updating the value of this.msg:

new Vue({
  el: '#app',
  data() {
    return { 
      msg: 'foo',
      value: 'text'
    }
  },
  updated() {
    this.msg = 'bar';
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
  {{ msg }}
  <input v-model="value"/>
</div>