Vue的this.$nextTick方法,异步更新dom详解
2022-08-04 本文已影响0人
前端末晨曦吖
Vue异步更新策略
在数据发生变化时,vue不会立刻更新DOM,而是开启一个队列,把组件更新函数保存在队列中,
在同一时间循环中发生的所有数据变更都保存在队列,一次性清空队列,一次性更新。
this.$nextTick(回调函数)
这个就是处理vue中DOM的异步更新的,在数据发生改变时,渲染DOM之后,会自动执行回调函数。
案例:
<template>
<div id="app">
<h1 ref="msgRef">msg: {{ msg }}</h1>
<button @click="change">点击改变msg的值</button>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
msg:'末晨曦吖',
}
},
methods:{
change() {
// 改变msg的值
this.msg = '改变后msg值'
// 输出节点的内容,这个时候虽然数据改变了,但DOM还没有更新,所以取到的还是msg之前的值 末晨曦吖
console.log('msgRef', this.$refs.msgRef['innerHTML']);
this.$nextTick(() => {
// 使用this.$nextTick()之后,里面的内容在DOM更新之后执行,所以取到的是msg修改之后的值
console.log('使用this.$nextTick()之后输出', this.$refs.msgRef.innerHTML);
});
}
}
}
</script>
<style scoped>
</style>
效果:
主要看输出部分:这个输出取到的是页面DOM的值,直接输出的话是改变之前的值,虽然数据发生改变,但这时DOM值还没有变,取DOM值是 '末晨曦吖'。
而使用this.$nextTick()
后,this.$nextTick()的回调函数在渲染完DOM后自动执行,所以这时的DOM值也已经改变了。所以取到的是新的值 “改变后msg值”。
常用场景:
1、 当在created()中想获取DOM时可以使用,根据vue的生命周期,页面的DOM是在mounted()时创建,在created()时还没有创建。
<template>
<div id="app">
<h1 ref="msgRef">msg: {{ msg }}</h1>
<button @click="change">点击改变msg的值</button>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
msg:'末晨曦吖',
}
},
created(){
console.log(111);
// 等DOM创建之后才会执行
this.$nextTick(() => {
console.log(222);
});
},
mounted(){
console.log(333);
this.$nextTick(() => {
console.log(444);
});
},
methods:{
change() {
// 改变msg的值
this.msg = '改变后msg值'
// 输出节点的内容,这个时候虽然数据改变了,但DOM还没有更新,所以取到的还是msg之前的值 末晨曦吖
console.log('msgRef', this.$refs.msgRef['innerHTML']);
this.$nextTick(() => {
// 使用this.$nextTick()之后,里面的内容在DOM更新之后执行,所以取到的是msg修改之后的值
console.log('使用this.$nextTick()之后输出', this.$refs.msgRef.innerHTML);
});
}
}
}
</script>
<style scoped>
</style>
效果:
created()会先执行,没有生成DOM, 所以created()中的this.$nextTick()
没有执行,继续向下执行mounted()中的内容,所以会先输出333,这时页面中DOM生成,执行created()中this.$nextTick()的回调函数,输出222。
2、响应式数据变化后获取DOM更新后的状态,比如新增或删除列表后,希望获取列表更新后的高度等场景,都可以使用this.$nextTick().