WHAT - vue3 nextTick 机制

Vue.js 3 中的 nextTick 机制是用于在 DOM 更新后执行回调函数的一种方式。它确保你在 Vue 更新 DOM 后立即操作 DOM 或访问更新后的 DOM。

在 Vue 3 中,nextTick 被重构为一个异步任务队列,它在渲染阶段之后执行。让我们通过源代码来详细解释 nextTick 的实现:

// 在 Vue 3 源代码中,nextTick 的核心实现在 scheduler.js 中

// 创建一个空数组,用于存储回调函数
const callbacks = []
let pending = false

// flushCallbacks 函数将会在下一个微任务中执行所有的回调函数
function flushCallbacks() {
  // 将 pending 置为 false,表示当前没有待执行的回调函数
  pending = false
  // 拷贝 callbacks 数组,以防止在执行回调时 callbacks 数组被修改
  const copies = callbacks.slice(0)
  // 清空原 callbacks 数组
  callbacks.length = 0
  // 遍历执行拷贝的回调函数
  for (let i = 0; i < copies.length; i++) {
    copies[i]()
  }
}

// 使用微任务来异步执行回调函数
let timerFunc

if (typeof Promise !== 'undefined') {
  // 如果支持 Promise,则使用 Promise.then 来异步执行回调
  timerFunc = () => {
    Promise.resolve().then(flushCallbacks)
  }
} else if (typeof MutationObserver !== 'undefined') {
  // 如果支持 MutationObserver,则使用 MutationObserver 来异步执行回调
  let counter = 1
  const observer = new MutationObserver(flushCallbacks)
  const textNode = document.createTextNode(String(counter))
  observer.observe(textNode, {
    characterData: true
  })
  timerFunc = () => {
    counter = (counter + 1) % 2
    textNode.data = String(counter)
  }
} else {
  // 如果不支持以上方式,则使用 setTimeout 来异步执行回调
  timerFunc = () => {
    setTimeout(flushCallbacks, 0)
  }
}

// nextTick 函数用于将回调函数添加到 callbacks 数组中
export function nextTick(callback, ctx) {
  callbacks.push(() => {
    if (callback) {
      try {
        callback.call(ctx)
      } catch (e) {
        // handle error
        console.error(e)
      }
    }
  })
  // 如果当前没有待执行的回调函数,则设置 pending 为 true,并调用 timerFunc
  if (!pending) {
    pending = true
    timerFunc()
  }
}

这段代码中,我们可以看到 nextTick 函数的核心实现:

  1. nextTick 接受一个回调函数,并将其添加到 callbacks 数组中。
  2. 如果当前没有待执行的回调函数,它会将 pending 设置为 true,然后调用 timerFunc 来异步执行回调函数。
  3. timerFunc 函数负责根据环境选择合适的异步方式来执行回调函数。它首先尝试使用 Promise,如果不支持 Promise,则尝试使用 MutationObserver,如果还不支持,则退化为使用 setTimeout。

总的来说,Vue 3 中的 nextTick 机制保证了在 DOM 更新后异步执行回调函数,以便我们能够安全地操作更新后的 DOM。

有关 Promise、MutationObserver、setTimeout 事件循环机制更多内容可以阅读 WHAT - 前端事件循环(Event Loop)机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@PHARAOH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值