Vue中$nextTick入门教程
官方定义:
在下次
DOM
更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM
。
理解:vue
在数据发生变化的时候并不会立即去更新 dom
,而是开启一个异步更新队列,等待同一事件循环中所有的数据变化完成后,再进行 Dom
更新,所以更新 dom
的过程是异步执行的,此时我们想获取最新的 dom
就需要借助 $nextTick()
辅助函数。
举个🌰
<template>
<div class="box">
<div ref="dom">{{ msg }}</div>
<el-button @click="update">点击更新</el-button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "更新前",
};
},
methods: {
update() {
this.msg = "222";
this.msg = "333";
this.msg = "444";
console.log(this.$refs.dom.innerHTML); // 初始值
},
},
};
</script>
分析:当我们触发 update
事件更新页面时候,我们发现 update
中获取不到更新后页面的值,这是由于 vue
在页面更新的时候采用的异步更新策略。 vue
会将同一个事件循环中所有需要修改的数据放在同一个异步队列中。(这里我们看到 msg
被修改了三次,实际在异步队列中只修改了一次。 )这是由于对于一直修改的数据,异步队列会进行去重处理。当同一事件循环中的数据更新完成后,才会将队列中的 update
事件进行处理,更新 Dom
。
为什么要使用异步更新策略?
{{num}}
for(let i=0; i<100000; i++){
num = i
}
分析:比如上面这串代码,如果同步更新,每次循环都会更新页面,那么页面会更新 100000
次,这就造成了不必要的性能浪费。
$nextTick 的使用
<template>
<div class="box">
<div ref="dom">{{ msg }}</div>
<el-button @click="update">点击更新</el-button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "更新前",
};
},
methods: {
update() {
this.msg = "222";
this.msg = "333";
this.msg = "444";
this.$nextTick(() => {
console.log(this.$refs.dom.innerHTML); // 444
});
console.log(this.$nextTick()); // Promise {<pending>}
},
},
};
</script>
分析: 仍然是上面的 🌰,为什么在 $nextTick
的回调中可以获取到最新的 Dom
?首先我们在控制台可以看到 $nextTick
本质是一个 Promise 对象。所以$nextTick
中执行的是一个异步的操作。
再举个🌰
<template>
<div>
<div ref="dom">{{ msg }}</div>
<el-button @click="update">点击更新</el-button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "更新前",
};
},
methods: {
update() {
this.msg = "222";
this.msg = "333";
this.msg = "444";
setTimeout(() => {
this.msg = "555";
});
Promise.resolve((this.msg = "666"));
this.$nextTick(() => {
console.log(this.$refs.dom.innerHTML); // 666
});
},
},
};
</script>
分析: 在上面的栗子上如果加上 setTimeout
和 Promise
呢? 浏览器中的 msg
变成了 555
但是获取最新的 Dom
值仍然是 666
。这是由于 Promise.resolve 是微任务,而setTimeout
是宏任务,所以这里相当于重新开启了一个事件循环。如果不理解建议看下 javaScript浅谈----事件循环(event loop)。
使用场景:
- 在
created
中获取dom
。 - 响应式数据更新完成后获取
dom
的更新状态,比如添加或者删除列表的中的一项,获取列表的高度。
转载自:https://juejin.cn/post/7225009769093234745