Vue之nextTick工作原理与作用

简介:vue的nextTick底层执行过程和作用

Vue 作为目前最为主流的前端 MVVM 框架之一,在熟练使用的基础上,去深入理解其实现原理是非常有意义的一件事情。

vue中的nextTick的工作原来

可能你还没有注意到,Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 Watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。

下面是 $nextTick 方法的大致执行过程

  1. 当调用 this.$nextTick(callback) 时,Vue 会将 callback 函数添加到一个称为“更新队列”(Update Queue)的数组中。
  2. Vue 会检查是否已经有一个异步任务正在进行中。如果没有,它会创建一个微任务,该微任务将在当前代码执行完成后执行。
  3. 当前代码执行完成并进入微任务队列时,Vue 将开始处理更新队列中的回调函数。
  4. 在处理更新队列时,Vue 会执行所有在该更新循环中触发的数据变更操作,并将这些变更应用到虚拟 DOM
  5. 完成虚拟 DOM 的更新后,Vue 会触发一个“flush”阶段,此时更新队列中的回调函数会被依次执行。
  6. 回调函数在执行时,DOM 已经更新完成,可以在回调函数中获取到更新后的 DOM

通过这样的异步处理方式,Vue 在下次 DOM 更新循环结束后执行 $nextTick 的回调函数,确保在回调函数内部能够获取到最新的 DOM 数据。

注意:Vue 在内部对异步队列尝试使用原生的 Promise.thenMutationObserversetImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。

使用 $nextTick 的常见场景是在更新数据后,立即获取更新后的 DOM 元素的状态,例如计算 DOM 元素的尺寸或位置。另一个常见用例是在修改数据后,执行某些依赖于更新后的数据的操作,确保在 DOM 更新完成后执行这些操作。

<template>
  <div>
    <p>计数:{{ count }}</p>
    <button @click="increment">增加计数</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    increment() {
      this.count++;
      // 在下次 DOM 更新循环结束后执行回调函数
      this.$nextTick(() => {
        // DOM 已更新,可以执行额外操作
        this.logElementSize();
      });
    },
    logElementSize() {
      // 获取元素尺寸
      const element = this.$el.querySelector('p');
      const { width, height } = element.getBoundingClientRect();
      console.log('元素宽度:', width, '元素高度:', height);
    },
  },
};
</script>

vue2和vue3中的$nextTick的区别

在vue2中$nextTick是一个全局函数,可以直接通过 this.$nextTickcallback() 调用。具体使用如下:

this.$nextTick(() => {
  // 在 DOM 更新后执行的回调函数
});

在vue3中$nextTick不再作为VUE实例的方法,而是一个独立的函数,需要使用时导入。此外nextTick返回的是一个Promise对象。因此,我们不仅可以通过传入函数处理回调,还可以通过 .then() 来处理回调:

// Vue 3 中的 nextTick
import { nextTick } from 'vue';

nextTick(()=>{
 // 在 DOM 更新后执行的回调函数
})

nextTick().then(() => {
  // 在 DOM 更新后执行的回调函数
});

// 或使用异步函数和 await
async function someFunction() {
  // ...修改数据
  await nextTick();
  // 在 DOM 更新后执行的回调函数
}

总结:

Vue 3 中的 $nextTick 与 Vue 2 中的 $nextTick 在功能上基本一致,都用于在下次 DOM 更新循环结束后执行回调函数。然而,Vue 3 中的 $nextTick 被作为一个独立的函数导入,并返回一个 Promise 对象,而不再作为 Vue 实例的方法。这样的改变使得代码更加清晰,并且能够更好地与现代 JavaScript 中的 Promise 和异步函数结合使用。

有遗漏或者不对的可以在我的公众号留言哦

 

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1