亚洲免费在线视频-亚洲啊v-久久免费精品视频-国产精品va-看片地址-成人在线视频网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

全面解析Vue中的$nextTick

瀏覽:15日期:2022-10-16 17:28:33

當(dāng)在代碼中更新了數(shù)據(jù),并希望等到對(duì)應(yīng)的Dom更新之后,再執(zhí)行一些邏輯。這時(shí),我們就會(huì)用到$nextTick

funcion callback(){ //等待Dom更新,然后搞點(diǎn)事。}$nextTick(callback);

官方文檔對(duì)nextTick的解釋是:

在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個(gè)方法,獲取更新后的 DOM。

那么,Vue是如何做的這一點(diǎn)的,是不是在調(diào)用修改Dom的Api之后(appendChild, textContent = 'xxxxx' 諸如此類),調(diào)用了我們的回調(diào)函數(shù)?實(shí)際上發(fā)生了什么呢。

源碼

nextTick的實(shí)現(xiàn)邏輯在這個(gè)文件里:

vue/src/core/util/next-tick.js

我們調(diào)用的this.$nextTick實(shí)際上是這個(gè)方法:

export function nextTick (cb?: Function, ctx?: Object) { 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() } // $flow-disable-line if (!cb && typeof Promise !== ’undefined’) { return new Promise(resolve => { _resolve = resolve }) }}

可以看到

回調(diào)函數(shù)被存放到了一個(gè)數(shù)組里:callbacks。 如果沒(méi)有傳遞回調(diào)函數(shù),這個(gè)方法會(huì)返回一個(gè)Promise,然后吧reslove當(dāng)成回調(diào)函數(shù)放到flushCallbacks中。所以文檔解釋了把本該當(dāng)成回調(diào)函數(shù)的callbacks放到then里的用法。 然后,有一個(gè)變量叫pending,如果不在pending中,則執(zhí)行函數(shù)timerFunc。而且pending默認(rèn)等于false。 flushCallbacks這個(gè)函數(shù)會(huì)一口氣執(zhí)行所有回調(diào)函數(shù)。 timerFunc

timerFunc定義在這里

可以看到timerFunc是在一個(gè)已resolve了的Promise的then 中執(zhí)行了flushCallbacks.

利用了js事件循環(huán)的微任務(wù)的機(jī)制

所以,每當(dāng)我們調(diào)用$nextTick,如果pending為false,就會(huì)調(diào)用timerFunc,然后timerFunc會(huì)把flushCallbacks給塞到事件循環(huán)的隊(duì)尾,等待被調(diào)用。

if (typeof Promise !== ’undefined’ && isNative(Promise)) { const p = Promise.resolve() timerFunc = () => { p.then(flushCallbacks) }}flushCallbacks

然后在這個(gè)文件里還有一個(gè)函數(shù)叫:flushCallbacks用來(lái)把保存的回調(diào)函數(shù)給全執(zhí)行并清空。

function flushCallbacks () { pending = false const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i < copies.length; i++) { copies[i]() }}pending

什么時(shí)候pending為true呢?

從timerFunc被調(diào)用到flushCallbacks被調(diào)用期間pending為true

即一個(gè)事件循環(huán)周期

在pending期間加入的回調(diào)函數(shù),會(huì)被已經(jīng)等待執(zhí)行的flushCallbacks函數(shù)給執(zhí)行。

核心機(jī)制

看完源碼,發(fā)現(xiàn)除了利用了一個(gè)微任務(wù)的機(jī)制,和Dom更新一點(diǎn)關(guān)系都沒(méi)有哇。

其實(shí)調(diào)用nextTick的不僅是開(kāi)發(fā)者,Vue更新Dom時(shí),也用到了nextTick。

開(kāi)發(fā)者更新綁定的數(shù)據(jù)之后,Vue就會(huì)立刻調(diào)用nextTick,把更新Dom的回調(diào)函數(shù)作為微任務(wù)塞到事件循環(huán)里去。

于是,在微任務(wù)隊(duì)列中,開(kāi)發(fā)者調(diào)用的nextTick的回調(diào)函數(shù),就一定在更行Dom的回調(diào)函數(shù)之后執(zhí)行了。

但是問(wèn)題又來(lái)了,根據(jù)瀏覽器的渲染機(jī)制,渲染線程是在微任務(wù)執(zhí)行完成之后運(yùn)行的。渲染線程沒(méi)運(yùn)行,怎么拿到Dom呢?

因?yàn)?,渲染線程只是把Dom樹(shù)渲染成UI而已,Vue更新Dom之后,在Dom樹(shù)里,新的Dom節(jié)點(diǎn)已經(jīng)存在了,js線程就已經(jīng)可以拿到新的Dom了。除非開(kāi)發(fā)者讀取Dom的計(jì)算屬性,觸發(fā)了強(qiáng)制重流渲染線程才會(huì)打斷js線程。

總結(jié) 首先timerFunc函數(shù)負(fù)責(zé)把回調(diào)函數(shù)們都丟到事件循環(huán)的隊(duì)尾 然后,nextTick函數(shù)負(fù)責(zé)把回調(diào)函數(shù)們都保存起來(lái)。 調(diào)用nextTick函數(shù)時(shí)會(huì)調(diào)用timerFunc函數(shù) Vue更新Dom也會(huì)使用nextTick,而且在開(kāi)發(fā)者調(diào)用nextTick之前。 因?yàn)?中的先后關(guān)系和事件循環(huán)的隊(duì)列性質(zhì),確保了開(kāi)發(fā)者的nextTick的回調(diào)一定在Dom更新之后

以上就是解析Vue中的$nextTick的詳細(xì)內(nèi)容,更多關(guān)于Vue中的$nextTick的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Vue
相關(guān)文章:
主站蜘蛛池模板: 日本黄大片影院一区二区 | 狠狠色丁香婷婷综合久久来 | 一级待一黄aaa大片在线还看 | 成年人网站免费视频 | 三级黄色在线 | 欧美区一区二 | 亚洲男人的性天堂 | 日韩免费观看的一级毛片 | 欧日韩美香蕉在线观看 | 韩国欧洲一级毛片 | 亚洲免费成人 | 国产成人亚洲综合网站不卡 | 在线观看日本永久免费视频 | 国产v综合v亚洲欧美大另类 | 波多野结衣福利视频 | 一色屋成人免费精品网站 | 亚洲精品美女视频 | 久久精品高清视频 | 亚洲人成网站在线观看播放 | 欧美成人免费全部色播 | 久草在线免费看 | 美女张开腿让人捅 | 亚洲综合精品一区二区三区中文 | 一级做a爰片久久毛片免费看 | 韩国一级片视频 | 久久99精品久久久久久久野外 | 女初高中福利视频在线观看 | 久草天堂| 在线综合+亚洲+欧美中文字幕 | 三级伦理网站 | 亚洲精品欧美日韩 | 国产高清一区二区三区免费视频 | 亚洲精品国产成人7777 | 午夜精品尤物福利视频在线 | 三级全黄a | 99久热在线精品视频观看 | 欧美一级淫片免费观看 | 91久久精一区二区三区大全 | 欧美一级视频免费看 | 日本欧美一区二区三区视频 | 国产呦精品一区二区三区网站 |