vue nexttick 实现
Vue nextTick 实现原理
Vue 的 nextTick 用于在下次 DOM 更新循环结束之后执行延迟回调,常用于获取更新后的 DOM 状态。其核心实现基于 JavaScript 的事件循环机制。
源码实现分析
Vue 2.x 和 Vue 3.x 的 nextTick 实现略有不同,但核心逻辑类似。以下是关键实现逻辑:
// Vue 2.x 实现
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]()
}
}
let timerFunc
// 优先使用微任务
if (typeof Promise !== 'undefined') {
const p = Promise.resolve()
timerFunc = () => {
p.then(flushCallbacks)
}
} else if (typeof MutationObserver !== 'undefined') {
// 回退到 MutationObserver
} else if (typeof setImmediate !== 'undefined') {
// 回退到 setImmediate
} else {
// 最后使用 setTimeout
timerFunc = () => {
setTimeout(flushCallbacks, 0)
}
}
export function nextTick(cb, ctx) {
callbacks.push(() => {
if (cb) {
try {
cb.call(ctx)
} catch (e) {
handleError(e, ctx, 'nextTick')
}
}
})
if (!pending) {
pending = true
timerFunc()
}
}
实现机制
Vue 的 nextTick 通过维护一个回调队列实现异步执行。当调用 nextTick 时,回调函数会被推入队列,通过微任务或宏任务机制延迟执行。
微任务优先策略确保回调在 DOM 更新后立即执行。现代浏览器环境下通常使用 Promise.then,不支持时降级到 MutationObserver、setImmediate 或 setTimeout。
使用场景
// 获取更新后的 DOM
this.message = 'updated'
this.$nextTick(() => {
console.log(this.$el.textContent) // 输出 'updated'
})
// 结合 async/await
async updateMessage() {
this.message = 'updated'
await this.$nextTick()
console.log(this.$el.textContent)
}
注意事项
nextTick 的回调执行时机取决于 JavaScript 事件循环。微任务版本的 nextTick 会在当前事件循环的末尾执行,早于 setTimeout 等宏任务。

在 Vue 3 中,nextTick 直接基于 Promise 实现,不再考虑降级方案。其行为更一致,但原理与 Vue 2 类似。






