什么是Vue.nextTick()
官方解释:在下次 DOM
更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
。
注意:重点是获取更新后的DOM 就是在开发过程中有个需求是需要在created
阶段操作数据更新后的节点 这时候就需要用到Vue.nextTick()
原因
在created()
钩子函数执行的时候DOM
其实并未进行任何渲染,而此时进行DOM
操作无异于徒劳,所以在created
中一定要将DOM操作的js代码放进Vue.nextTick()
的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM
挂载和渲染都已完成,此时在该钩子函数中进行任何DOM
操作都不会有问题 。
案例一
<template>
<div id="app">
<div ref="msgDiv">{{msg1}}</div>
<br/>
<div>{{msg2}}</div>
<br/><br/>
<button @click="changeMsg">点击我</button>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
msg1: "你我贷",
msg2: "理财"
}
},
methods: {
changeMsg() {
this.msg1 = "飞旋"
this.msg2 = this.$refs.msgDiv.textContent;
console.log(this.$refs.msgDiv.textContent)
this.$nextTick(function(){
console.log(this.$refs.msgDiv.textContent)
})
}
}
}
</script>
触发前:
触发后:
案例二:
<template>
<div id="app">
<div ref="msgDiv" id="msgDiv" v-if="showDiv">{{msg1}}</div>
<button @click="changeMsg">点击我</button>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
msg1: "你我贷",
showDiv: false
}
},
methods: {
changeMsg() {
this.showDiv = true
console.log(document.getElementById("msgDiv"))
this.$nextTick(function(){
console.log(document.getElementById("msgDiv"))
})
}
}
}
</script>
点击前:
点击后:
注意:上面代码执行后第一次console.log(document.getElementById("msgDiv"))
输出的是null
这里涉及一个重要的概念 异步更新队列。Vue
在观察到数据变化时并不是直接更新DOM
,而是开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。在缓冲时会去除重复数据,从而避免不必要的计算和DOM
操作。然后,在下一个事件循环tick
中,Vue
刷新队列并执行实际工作。
事实上,在执行this.showDiv = true;
时,div
仍然还是没有被创建出来,直到下一个Vue
事件循环时,才开始创建。$nextTick
就是用来知道什么时候DOM
更新完成的,因此上述代码中第二个console.log(document.getElementById("msgDiv"))
输出的是<div id="msgDiv">你我贷</div>