DOM的更新是异步的,这就意味着,并不是你修改了数据,其对应的真实的DOM就会立马完成更新。
Vue的官方文档是这样说的:
可能你还没有注意到,Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。例如,当你设置 vm.someData = 'new value',该组件不会立即重新渲染。
可以通过代码验证:
<div id="app{{ text }}</div>
<script>
var vm = new Vue({
el: '#',
data: {
text: '我是旧值'
}
})
vm.text = '我是新值' // 更改了数据
console.log(vm.$el.textContent) // 打印值: 我是旧值
</script>
复制代码
虽然数据已经修改了,但修改后立刻访问DOM,仍是旧值。也代表着我们获取的不是最新的DOM,如何才能在DOM完成更新后操作DOM呢?这就需要使用到Vue提供的API,即Vue.nextTick。
Vue.nextTick
这个是Vue提供的API,它可以在DOM更新完毕之后执行一个回调。也就是说这个API能够检测DOM是否完成了更新,然后在DOM更新后执行回调。
<div id="app">{{ text }}</div>
<script>
var vm = new Vue({
el: '#app,
data: {
text: '我是旧值'
}
})
vm.text = '我是新值' // 更改了数据
Vue.nextTick(function(){
console.log(vm.$el.textContent) //打印值: 我是新值
})
</script>
复制代码
所以,官网也说过,mounted不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick。