为什么 nextTick ?

95 阅读1分钟

本文语境: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
};