如果在修改数据之后,需要立即获取被修改的元素,需要用到nextTick才可以获取到更新后的dom。
<template>
<div id="app">
<span ref="name">{{ name }}</span>
<button type="button" @click="change">改变</button>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
list: [1,2,3],
name: 'tom'
}
},
methods: {
change() {
this.name = 'lucy';
console.log(this.$refs.name.innerHTML, 'dom未更新'); // 输出tom
this.$nextTick(function (){
console.log(this.$refs.name.innerHTML, 'dom已更新'); // 输出tom
});
}
}
}
</script>
原因就在于,vue更新dom时,并不是同步更新的,而是异步更新。
js遇到异步时,会将其放入事件队列继续执行主线程的任务,当主线程执行完毕时,才会去事件队列执行异步任务。所以呢,我们直接输出的话,获取到的就是未更新数据。
- 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。
- 在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。
- 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。
vue还提供了Promise的写法,既:this.$nextTick().then()。