Vue中的nextTick涉及到Vue中DOM的异步更新
一、示例
先了解一下关于vue
中的DOM更新以及nextTick
的作用
<div class="app">
<div ref="msgDiv">{{msg}}</div>
<div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
<div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
<div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
<button @click="changeMsg">
Change the Message
</button>
</div>
new Vue({
el: '.app',
data: {
msg: 'Hello Vue.',
msg1: '',
msg2: '',
msg3: ''
},
methods: {
changeMsg() {
this.msg = "Hello world."
this.msg1 = this.$refs.msgDiv.innerHTML
this.$nextTick(() => {
this.msg2 = this.$refs.msgDiv.innerHTML
})
this.msg3 = this.$refs.msgDiv.innerHTML
}
}
})
点击前
点击后
从结果可知,msg1和msg3显示的内容还是变换之前的,而msg2的内容是变换之后的。原因是vue
中的DOM更新是异步的。
二、nextTick应用场景
- 在
Vue
生命周期的created()
钩子函数进行的DOM操作一定要放在Vue.nextTick()
的回调函数中
在create()
钩子函数执行的时候,DOM是没有进行渲染的,而此时对于DOM的操作代码一定要放进Vue.nextTick()
的回调函数中。也可以将DOM操作放在mounted()
钩子函数中,因为该钩子函数执行时所有的DOM挂载和渲染都已完成。 - 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作一定要放进
Vue.nextTick()
的回调函数中。
vue官方文档中的解释:
Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0)代替。