nextTick
?是 Vue 中非常重要的一個 API,它允許你在 DOM 更新周期后執行延遲回調。
核心源碼位置
Vue3 的?nextTick
?實現主要在?packages/runtime-core/src/scheduler.ts
?文件中。
基本實現
const resolvedPromise = Promise.resolve() as Promise<any>
let currentFlushPromise: Promise<void> | null = nullexport function nextTick<T = void>(this: T,fn?: (this: T) => void
): Promise<void> {const p = currentFlushPromise || resolvedPromisereturn fn ? p.then(this ? fn.bind(this) : fn) : p
}
關鍵點解析
-
Promise 基礎:
-
使用?
Promise.resolve()
?創建一個已解決的 Promise 作為基礎 -
這樣即使沒有正在進行的更新,也能返回一個可用的 Promise
-
-
currentFlushPromise:
-
這個變量保存著當前正在進行的更新流程的 Promise
-
如果有更新正在進行,
nextTick
?會返回這個 Promise 而不是基礎的?resolvedPromise
-
-
靈活的參數處理:
-
可以不帶參數調用,只返回 Promise
-
可以傳入回調函數,回調會在 Promise resolve 后執行
-
支持綁定?
this
?上下文
-
執行流程
-
當組件狀態發生變化時,Vue 會安排一個異步更新隊列
-
這個更新隊列的執行會設置?
currentFlushPromise
-
調用?
nextTick
?時:-
如果有更新正在進行(
currentFlushPromise
?存在),則回調會在這個 Promise 后執行 -
如果沒有更新進行,則回調會在微任務隊列中立即執行
-
為什么使用 Promise
Vue 3 使用 Promise 作為?nextTick
?的實現基礎,原因包括:
-
微任務優先級高于宏任務(如 setTimeout),能更早執行
-
現代瀏覽器廣泛支持 Promise
-
可以形成良好的 Promise 鏈式調用
與 Vue 2 的區別
Vue 2 中?nextTick
?的實現更加復雜,有一個降級策略:
-
優先使用 Promise
-
不支持 Promise 時回退到 MutationObserver
-
再不支持則使用 setImmediate
-
最后使用 setTimeout
Vue 3 簡化了實現,因為現代瀏覽器已普遍支持 Promise,不再需要復雜的降級策略。
使用場景
import { nextTick } from 'vue'// 基本用法
nextTick(() => {// DOM 更新后執行
})// 配合 async/await
async function update() {// 修改數據this.message = 'updated'await nextTick()// 現在 DOM 已經更新
}
nextTick
?是理解 Vue 響應式系統和更新機制的關鍵部分,它的簡潔實現體現了 Vue 3 對現代 JavaScript 特性的充分利用。
?
?