vue nexttrick实现

vue nextTick 的实现原理
Vue 的 nextTick 方法用于在下次 DOM 更新循环结束之后执行延迟回调。其核心实现基于 JavaScript 的事件循环机制,优先使用微任务(microtask)实现异步队列。
源码核心逻辑
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
// 优先使用 Promise
if (typeof Promise !== 'undefined') {
const p = Promise.resolve()
timerFunc = () => {
p.then(flushCallbacks)
}
}
// 降级方案
else if (typeof setImmediate !== 'undefined') {
timerFunc = () => {
setImmediate(flushCallbacks)
}
} else {
timerFunc = () => {
setTimeout(flushCallbacks, 0)
}
}
function nextTick(cb, ctx) {
let _resolve
callbacks.push(() => {
if (cb) {
try {
cb.call(ctx)
} catch (e) {
handleError(e, ctx, 'nextTick')
}
} else if (_resolve) {
_resolve(ctx)
}
})
if (!pending) {
pending = true
timerFunc()
}
if (!cb && typeof Promise !== 'undefined') {
return new Promise(resolve => {
_resolve = resolve
})
}
}
使用方式
// 回调函数方式
this.$nextTick(() => {
// DOM 更新后执行
})
// Promise 方式
this.$nextTick().then(() => {
// DOM 更新后执行
})
实现要点
- 异步队列:将回调函数收集到队列中,统一执行
- 微任务优先:优先使用
Promise.then创建微任务 - 降级策略:不支持 Promise 时降级到
setImmediate或setTimeout - 批量处理:通过
pending标志避免重复触发异步任务
与 DOM 更新的关系
Vue 的 DOM 更新也是通过 nextTick 机制实现的。当数据变化时,Vue 会将 DOM 更新操作和用户通过 nextTick 注册的回调都放入同一个异步队列,确保在同一个事件循环中执行。







