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


    一、问题分析

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

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

    1.nextTick()

    2.setTimeout()

    3.在微任务中获取

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

    二、执行顺序分析

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

    1. <template>
    2. <div class="page">
    3. <button
    4. @click="clickButton"
    5. ref="buttonRef"
    6. :style="{ height: `${height}px`, width: '60px' }"
    7. >button>
    8. <div class="info">{{ height }}div>
    9. div>
    10. template>
    11. <script setup lang="ts">
    12. import { nextTick, ref } from "vue";
    13. const height = ref(40);
    14. const buttonRef = ref();
    15. const clickButton = async () => {
    16. height.value = height.value + 10;
    17. console.log(buttonRef.value.style.height, "直接打印"); // 40px
    18. setTimeout(() => {
    19. console.log(buttonRef.value.style.height, "setTimeout0打印1"); // 50px
    20. }, 0);
    21. await console.log("dom已更新");
    22. setTimeout(() => {
    23. console.log(buttonRef.value.style.height, "setTimeout0打印2"); // 50px
    24. }, 0);
    25. setTimeout(() => {
    26. console.log(buttonRef.value.style.height, "setTimeout100打印"); // 50px
    27. }, 100);
    28. nextTick(() => {
    29. console.log(buttonRef.value.style.height, "nextTick打印"); // 50px
    30. });
    31. console.log("测试数据");
    32. console.log(buttonRef.value.style.height, "微任务打印"); // 50px
    33. };
    34. script>
    35. <style>
    36. .page {
    37. width: 100%;
    38. height: 100vh;
    39. display: flex;
    40. flex-direction: column;
    41. justify-content: center;
    42. align-items: center;
    43. }
    44. style>

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

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

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

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

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

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

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

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

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

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

  • 相关阅读:
    OpenWrt环境下,由于wget不支持ssl/tls导致执行opkg update失败的解决方法
    CentOS 软件包 rpm 管理学习笔记
    【QT】QTreeWidget
    CAD图形导出为XAML实践
    svo2.0 svo pro 编译运行
    《开箱元宇宙》:认识香港麦当劳通过 The Sandbox McNuggets Land 的 Web3 成功经验
    【C语言数据结构】队列-顺序存储(顺序队列)
    codesys TCP客户端程序
    tinyxml 代码解读
    一个web请求在springboot经历了什么
  • 原文地址:https://blog.csdn.net/qq_45820271/article/details/139752798