NextTick 在 Vue 中如何發(fā)揮作用的?其實(shí)大部分人一知半解
大家好,我是林三心,用最通俗易懂的話講最難的知識點(diǎn)是我的座右銘,基礎(chǔ)是進(jìn)階的前提是我的初心~
背景
我發(fā)現(xiàn)很多人背八股文真的背傻了,只知道 nextTick = 微任務(wù),其他啥都不知道,也不去了解原因,甚至大部分理解的都是錯(cuò)的?
先來回顧下nextTick的使用,因?yàn)?Vue 的響應(yīng)式變量是異步更新DOM的,所以當(dāng)你變量修改的時(shí)候,并不能第一時(shí)間拿到最新的 DOM,而在nextTick中就可以拿到最新的 DOM
圖片
先問是不是,再問為什么
很多人認(rèn)為 nextTick = 微任務(wù),這其實(shí)是錯(cuò)的,正確應(yīng)該是 nextTick 優(yōu)先是 微任務(wù),不信可以直接看 Vue 的源碼
在src\core\util\next-tick.ts 文件中,可以看到 nextTick 優(yōu)先級如下:
- Promise.resolve().then:微任務(wù)
- MutationObserver:宏任務(wù)
- setImmediate:宏任務(wù)
- setTimeout:宏任務(wù)
圖片
所以說 nextTick 只是優(yōu)先選擇微任務(wù)而已,當(dāng)瀏覽器不支持微任務(wù)的時(shí)候,它還是會選擇宏任務(wù)
為啥優(yōu)先微任務(wù)?
2023年面試了怎么也得有100個(gè)人了,大部分都不能比較好的回答這個(gè)問題:nextTick為啥優(yōu)先選擇微任務(wù)?
首先聲明一個(gè)點(diǎn):Vue 的異步更新DOM 其實(shí)也是微任務(wù),比如下面的例子,你一次性更新了三次變量,其實(shí)會生成三個(gè)更新DOM微任務(wù)到隊(duì)列中
圖片
你這個(gè)時(shí)候放一個(gè) nextTick 在后面,那就是在三個(gè)微任務(wù)后面再放一個(gè)微任務(wù)而已
圖片
我們都知道微任務(wù)是在UI渲染之前執(zhí)行的,那為什么 nextTick 能拿到最新的 DOM 呢?
圖片
更新 ≠ 渲染
其實(shí)我們要明白一個(gè)點(diǎn):更新 ≠ 渲染,前面三個(gè)更新微任務(wù)只是更新DOM,修改的是DOM樹,而使用 document.getElementById這類方法去獲取到的就是DOM樹的內(nèi)容
圖片
所以 nextTick 為什么是微任務(wù),但是能獲取到最新DOM呢?因?yàn)榈搅?nextTick 這一步的時(shí)候,DOM樹已經(jīng)更新完了,只是還沒渲染到頁面上而已,而我們能通過DOM的一些API去獲取到最新的DOM樹內(nèi)容,比如 document.getElementById 這類方法
所以,與其說 nextTick 能獲取到最新的DOM,還不如說 nextTick 能獲取到最新的DOM樹信息