色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術文章
文章詳情頁

全面解析Vue中的$nextTick

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

當在代碼中更新了數據,并希望等到對應的Dom更新之后,再執行一些邏輯。這時,我們就會用到$nextTick

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

官方文檔對nextTick的解釋是:

在下次 DOM 更新循環結束之后執行延遲回調。在修改數據之后立即使用這個方法,獲取更新后的 DOM。

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

源碼

nextTick的實現邏輯在這個文件里:

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

我們調用的this.$nextTick實際上是這個方法:

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 }) }}

可以看到

回調函數被存放到了一個數組里:callbacks。 如果沒有傳遞回調函數,這個方法會返回一個Promise,然后吧reslove當成回調函數放到flushCallbacks中。所以文檔解釋了把本該當成回調函數的callbacks放到then里的用法。 然后,有一個變量叫pending,如果不在pending中,則執行函數timerFunc。而且pending默認等于false。 flushCallbacks這個函數會一口氣執行所有回調函數。 timerFunc

timerFunc定義在這里

可以看到timerFunc是在一個已resolve了的Promise的then 中執行了flushCallbacks.

利用了js事件循環的微任務的機制

所以,每當我們調用$nextTick,如果pending為false,就會調用timerFunc,然后timerFunc會把flushCallbacks給塞到事件循環的隊尾,等待被調用。

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

然后在這個文件里還有一個函數叫:flushCallbacks用來把保存的回調函數給全執行并清空。

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

什么時候pending為true呢?

從timerFunc被調用到flushCallbacks被調用期間pending為true

即一個事件循環周期

在pending期間加入的回調函數,會被已經等待執行的flushCallbacks函數給執行。

核心機制

看完源碼,發現除了利用了一個微任務的機制,和Dom更新一點關系都沒有哇。

其實調用nextTick的不僅是開發者,Vue更新Dom時,也用到了nextTick。

開發者更新綁定的數據之后,Vue就會立刻調用nextTick,把更新Dom的回調函數作為微任務塞到事件循環里去。

于是,在微任務隊列中,開發者調用的nextTick的回調函數,就一定在更行Dom的回調函數之后執行了。

但是問題又來了,根據瀏覽器的渲染機制,渲染線程是在微任務執行完成之后運行的。渲染線程沒運行,怎么拿到Dom呢?

因為,渲染線程只是把Dom樹渲染成UI而已,Vue更新Dom之后,在Dom樹里,新的Dom節點已經存在了,js線程就已經可以拿到新的Dom了。除非開發者讀取Dom的計算屬性,觸發了強制重流渲染線程才會打斷js線程。

總結 首先timerFunc函數負責把回調函數們都丟到事件循環的隊尾 然后,nextTick函數負責把回調函數們都保存起來。 調用nextTick函數時會調用timerFunc函數 Vue更新Dom也會使用nextTick,而且在開發者調用nextTick之前。 因為4中的先后關系和事件循環的隊列性質,確保了開發者的nextTick的回調一定在Dom更新之后

以上就是解析Vue中的$nextTick的詳細內容,更多關于Vue中的$nextTick的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
主站蜘蛛池模板: 一级做a爱过程免费视 | 免费看一级毛片欧美 | 91理论片午午伦夜理片久久 | 亚州人成网在线播放 | 久久91亚洲精品中文字幕奶水 | caoporen免费公开视频上传 | 一区二区三区视频网站 | 韩国主播19福利视频在线 | 国产成人精品一区二三区 | 亚洲人成网站观看在线播放 | 手机毛片 | aaaaaaa一级毛片 | 92国产福利久久青青草原 | 动漫一级毛片 | 一级a欧美毛片 | 美女做爰视频在线观看免费 | 日韩在线观看一区 | 99久女女精品视频在线观看 | 久久曰视频| 日本成人免费在线观看 | 欧美一区二区三区不卡免费观看 | 亚洲综合国产一区在线 | 欧美色老头oldvideos | 亚洲欧美在线免费 | 青青影院一区二区免费视频 | 日本三级香港三级妇三 | 亚洲性综合 | 亚洲炮网| 欧美特级视频 | 亚洲国产精品一区二区三区 | 欧美在线观看高清一二三区 | 能在线观看的一区二区三区 | 亚欧免费视频 | 亚洲a网 | 一区二区三区高清在线 | 亚洲成人毛片 | 欧美激情第一欧美在线 | 久草热视频在线观看 | 欧美在线视频一区二区 | 久久超级碰 | 国产精品久久久久久福利漫画 |