本文语境:vue3
nextTick 是什么?
按官方的说法,nextTick是等待下一次DOM更新刷新的工具方法。意思是,使用它,我们等待DOM更新完成后,再执行我们的某些操作。
为什么需要等待下次更新呢?
当Vue的响应式状态变更时,DOM不会立即更新,而是将变更缓存到一个队列,在下一个更新周期统一更新。这样的好处是无论组件状态变更多少次,单位时间内都仅更新一次,避免不必要的重复渲染。但是,这样的机制会出现一个期望外的情况:在状态更新后立即获取DOM的属性,会获得到它的旧值。 如:
<template>
<div id="msgBox" @click="handleMsg">
{{ msg }}
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
let msg = ref("Hello Vue");
const handleMsg = () => {
msg.value = "Hello World";
console.log(document.getElementById("msgBox")?.innerHTML);
// msg已更改为Hello World,但打印的是旧值 Hello Vue
};
</script>
使用nextTick可以避免这种情况,它可以等待DOM更新完成后,去得到它的新值。
怎么使用nextTick?
nextTick有两种使用方式,回调函数和async/await。
1. 传入回调函数方式
给nextTick传入一个回调函数,在回调函数中获取DOM
const handleMsg = () => {
msg.value = "Hello World";
console.log(document.getElementById("msgBox")?.innerHTML);
// msg已更改为Hello World,但打印的是旧值 Hello Vue
nextTick(() => {
console.log(document.getElementById("msgBox")?.innerHTML);
// 打印的是新值 Hello World
});
};
2. async/await方式
const handleMsg = async () => {
msg.value = "Hello World";
console.log(document.getElementById("msgBox")?.innerHTML);
// msg已更改为Hello World,但打印的是旧值 Hello Vue
await nextTick();
console.log(document.getElementById("msgBox")?.innerHTML);
// 打印的是新值 Hello World
};