当前位置:首页 > VUE

vue $nexttick如何实现的

2026-01-21 05:43:57VUE

Vue $nextTick 的实现原理

Vue 的 $nextTick 方法用于在 DOM 更新完成后执行回调函数。其核心实现依赖于 JavaScript 的事件循环机制和微任务/宏任务的调度。

基于微任务的异步队列

Vue 在内部维护一个回调队列,$nextTick 会将回调函数推入这个队列。Vue 会根据当前环境选择最优的异步调度方式:

  • Promise(首选):现代浏览器支持的原生微任务 API,优先级最高。

    vue $nexttick如何实现的

    if (typeof Promise !== 'undefined') {
      const p = Promise.resolve()
      timerFunc = () => p.then(flushCallbacks)
    }
  • MutationObserver:作为 Promise 的降级方案,同样是微任务。

    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)
    }
  • setImmediate:Node.js 环境的高效宏任务。

    vue $nexttick如何实现的

    if (typeof setImmediate !== 'undefined') {
      timerFunc = () => setImmediate(flushCallbacks)
    }
  • setTimeout:最终的兼容性兜底方案。

    timerFunc = () => setTimeout(flushCallbacks, 0)

执行流程

  1. 回调收集:调用 $nextTick(callback) 时,回调被推入 callbacks 数组。
  2. 异步触发:通过 timerFunc 调度 flushCallbacks 执行。
  3. 队列处理flushCallbacks 会复制当前队列并依次执行所有回调,同时清空队列。

源码关键逻辑

const callbacks = []
let pending = false

function flushCallbacks() {
  pending = false
  const copies = callbacks.slice(0)
  callbacks.length = 0
  for (let i = 0; i < copies.length; i++) {
    copies[i]()
  }
}

function nextTick(cb, ctx) {
  callbacks.push(() => {
    if (cb) cb.call(ctx)
  })
  if (!pending) {
    pending = true
    timerFunc()
  }
}

与数据更新的关系

当响应式数据变化时,Vue 的更新也是通过 nextTick 实现的异步队列:

  • 数据变更触发 dep.notify()
  • watcher.update() 将渲染 watcher 加入队列
  • nextTick(flushSchedulerQueue) 确保更新在下次事件循环执行

这种设计保证了:

  • 同一事件循环内的多次数据变更只会触发一次渲染
  • 在回调中能获取更新后的 DOM
  • 避免不必要的重复计算

标签: 如何实现vue
分享给朋友:

相关文章

vue实现多级表头

vue实现多级表头

Vue 实现多级表头的方法 使用 el-table 组件 Element UI 的 el-table 组件支持多级表头的实现,通过嵌套 el-table-column 即可完成。 <el-ta…

vue实现压缩上传文件

vue实现压缩上传文件

压缩上传文件的实现方法 在Vue中实现文件压缩和上传功能,可以通过以下步骤完成。该方法结合了前端文件压缩库和HTTP请求,确保文件在上传前被有效压缩。 安装必要的依赖 需要使用compressorj…

vue前端折线如何实现

vue前端折线如何实现

使用 Vue 实现折线图的方法 安装图表库 推荐使用 ECharts 或 Chart.js 等主流图表库。以 ECharts 为例,通过 npm 安装: npm install echarts vu…

vue穿梭框组件实现

vue穿梭框组件实现

实现基础穿梭框组件 在Vue中实现穿梭框组件,可以使用<el-transfer>(Element UI)或手动实现。以下是手动实现的核心逻辑: <template> &…

vue实现建模

vue实现建模

Vue 实现建模的方法 在 Vue 中实现建模通常涉及数据绑定、组件化和状态管理。以下是几种常见的方法: 数据驱动建模 Vue 的核心是数据驱动视图。通过定义数据模型,Vue 会自动更新 DOM。…

vue 实现列表

vue 实现列表

Vue 实现列表的方法 在 Vue 中实现列表通常使用 v-for 指令,结合数组或对象数据渲染动态列表。以下是几种常见的实现方式: 基础列表渲染 使用 v-for 指令遍历数组,渲染列表项。ite…