vue:对三种获取更新后的dom的方式进行分析

一、问题分析

由于vue的异步更新机制,我们在同步代码中是无法获取到更新后的dom的信息的

针对这个问题,我们有三种解决方案获取更新后的dom:

1.nextTick()

2.setTimeout()

3.在微任务中获取

因为更新是在同步任务结束后,执行微任务之前,所以上面三种方式可以得到更新后的dom。

二、执行顺序分析

先看代码,下面的代码中,通过点击使得绑定的按钮元素高度增加,在js中通过打印来去观察不同获取该元素信息的方式的区别。

<template>
  <div class="page">
    <button
      @click="clickButton"
      ref="buttonRef"
      :style="{ height: `${height}px`, width: '60px' }"
    ></button>
    <div class="info">{{ height }}</div>
  </div>
</template>
<script setup lang="ts">
import { nextTick, ref } from "vue";
const height = ref(40);
const buttonRef = ref();
const clickButton = async () => {
  height.value = height.value + 10;
  console.log(buttonRef.value.style.height, "直接打印"); // 40px
  setTimeout(() => {
    console.log(buttonRef.value.style.height, "setTimeout0打印1"); // 50px
  }, 0);
  await console.log("dom已更新");
  setTimeout(() => {
    console.log(buttonRef.value.style.height, "setTimeout0打印2"); // 50px
  }, 0);
  setTimeout(() => {
    console.log(buttonRef.value.style.height, "setTimeout100打印"); // 50px
  }, 100);
  nextTick(() => {
    console.log(buttonRef.value.style.height, "nextTick打印"); // 50px
  });
  console.log("测试数据");
  console.log(buttonRef.value.style.height, "微任务打印"); // 50px
};
</script>
<style>
.page {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
</style>

我们可以观察到,除了在同步代码中获取按钮元素的信息,都得到了更新后的按钮高度。同时我们可以发现,nextTick中的任务是在微任务队列的末尾的,如果把这段代码提前到同步任务中也是同样的效果。

由此,我们可以得出结论,获取更新后dom的速度,微任务中获取>nextTick中获取>宏任务中获取

三、为什么nextTick让任务进入微任务队列末尾而不是开头或者中间

1.避免无限循环。如果 nextTick 的回调被添加到队列的开头,那么在执行回调的过程中再次调用 nextTick 可能会导致无限循环,因为新产生的 nextTick 任务会立即执行,从而可能不断地往队列中添加新的任务。

2.性能优化。vue的异步更新是为了让同一个Tick中的数据变化完了再更新,将任务放入末尾也是同样的目的,可以尽可能减少不必要的dom操作。

3.便于调试。如果这个任务会到处都是那么数据的变化是难以预测的。

四、为什么优先使用nextTick()

1.nextTick的作用就是告诉vue这个dom更新好了,简单,稳定,可靠,语义强。

2.方便调试,避免无限循环,性能优化。

3.不用像settimeout一样把任务拖到下一个宏任务。

相关推荐

  1. Vue3: 获取元素DOM方法

    2024-06-18 17:16:01       50 阅读
  2. 获取页面标签元素dom方法

    2024-06-18 17:16:01       57 阅读
  3. mybatis 实现批量更新方式

    2024-06-18 17:16:01       49 阅读
  4. 解决vuex刷新页面数据丢失方法

    2024-06-18 17:16:01       41 阅读
  5. vue项目获取 iframe 中DOM元素

    2024-06-18 17:16:01       60 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-18 17:16:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-18 17:16:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-18 17:16:01       87 阅读
  4. Python语言-面向对象

    2024-06-18 17:16:01       96 阅读

热门阅读

  1. stringstream的使用

    2024-06-18 17:16:01       33 阅读
  2. Spring Boot常用注解

    2024-06-18 17:16:01       34 阅读
  3. 近期学习文章

    2024-06-18 17:16:01       31 阅读
  4. 2024.06.05校招 实习 内推 面经

    2024-06-18 17:16:01       33 阅读
  5. 日语 9 10

    2024-06-18 17:16:01       35 阅读
  6. Swift Combine — Publisher、Operator、Subscriber概念介绍

    2024-06-18 17:16:01       32 阅读
  7. Thymeleaf 全局变量

    2024-06-18 17:16:01       36 阅读
  8. 微信小程序---支付

    2024-06-18 17:16:01       30 阅读
  9. CORE公链

    2024-06-18 17:16:01       31 阅读
  10. 分数限制下,选好专业还是选好学校?

    2024-06-18 17:16:01       35 阅读
  11. linux上运行js脚本

    2024-06-18 17:16:01       28 阅读