vue中nexttick实现
Vue中nextTick的实现原理
Vue的nextTick方法用于在DOM更新循环结束之后执行延迟回调,确保操作基于更新后的DOM。其核心实现涉及JavaScript事件循环机制和Vue的异步更新队列。
实现机制
Vue通过维护一个回调队列(callbacks数组)来实现nextTick。当调用nextTick时,回调函数会被推入这个队列。Vue采用微任务(microtask)优先的策略来执行这些回调,具体通过以下方式:

-
优先使用Promise:现代浏览器支持Promise时,Vue会用
Promise.resolve().then(flushCallbacks)将回调包装为微任务。if (typeof Promise !== 'undefined') { const p = Promise.resolve() timerFunc = () => { p.then(flushCallbacks) } } -
降级方案:若不支持Promise,会依次尝试
MutationObserver、setImmediate,最终降级为setTimeout宏任务。
else if (typeof MutationObserver !== 'undefined') { 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) } }
执行流程
- 队列收集:多次调用
nextTick时,回调会被合并到同一队列,避免重复触发任务调度。 - 异步执行:通过
timerFunc将flushCallbacks推入任务队列,在事件循环的适当时机清空回调队列。function flushCallbacks() { const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i < copies.length; i++) { copies[i]() } }
应用场景
-
DOM更新后操作:如获取更新后的DOM元素尺寸。
this.message = 'updated' this.$nextTick(() => { console.log(document.getElementById('el').textContent) // 输出'updated' }) -
组件渲染后访问子组件:确保子组件已渲染完成。
注意事项
- 微任务执行时机早于宏任务,能更快触发UI渲染。
- 避免在
nextTick中执行耗时操作,以免阻塞页面交互。






