91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

$nextTick在Vue中的作用是什么

發布時間:2020-12-24 16:10:47 來源:億速云 閱讀:293 作者:Leah 欄目:開發技術

這篇文章給大家介紹$nextTick在Vue中的作用是什么,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

當在代碼中更新了數據,并希望等到對應的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
  })
 }
}

可以看到

  1. 回調函數被存放到了一個數組里:callbacks。

  2. 如果沒有傳遞回調函數,這個方法會返回一個Promise,然后吧reslove當成回調函數放到flushCallbacks中。所以文檔解釋了把本該當成回調函數的callbacks放到then里的用法。

  3. 然后,有一個變量叫pending,如果不在pending中,則執行函數timerFunc。而且pending默認等于false。

  4. 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線程。

總結

  1. 首先timerFunc函數負責把回調函數們都丟到事件循環的隊尾

  2. 然后,nextTick函數負責把回調函數們都保存起來。

  3. 調用nextTick函數時會調用timerFunc函數

  4. Vue更新Dom也會使用nextTick,而且在開發者調用nextTick之前。

  5. 因為4中的先后關系和事件循環的隊列性質,確保了開發者的nextTick的回調一定在Dom更新之后

關于$nextTick在Vue中的作用是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

招远市| 新建县| 陆丰市| 克什克腾旗| 德清县| 合川市| 黄大仙区| 武义县| 馆陶县| 新民市| 卓资县| 晋州市| 宝应县| 伊春市| 博乐市| 正安县| 云霄县| 革吉县| 海盐县| 丹巴县| 五大连池市| 安西县| 祁门县| 崇信县| 昌黎县| 浮梁县| 花垣县| 洪雅县| 阜新市| 建昌县| 女性| 虹口区| 武平县| 昭觉县| 调兵山市| 山阴县| 辽宁省| 保德县| 旬邑县| 嘉黎县| 安溪县|