天天看點

Vue.nextTick

1、nextTick就提供了一個橋梁,確定我們操作的是更新後的DOM。

2、事件循環機制

簡要來說,事件循環會維護一個或多個任務隊列(task queues),以上提到的事件作為任務源往隊列中加入任務。有一個持續執行的線程來處理這些任務,每執行完一個就從隊列中移除它,這就是一次事件循環了,如下圖所示:

Vue.nextTick

我們平時用setTimeout來執行異步代碼,其實就是在任務隊列的末尾加入了一個task,待前面的任務都執行完後再執行它。

關鍵的地方來了,每次event loop的最後,會有一個UI render步驟,也就是更新DOM。标準為什麼這樣設計呢?考慮下面的代碼:

for(let i=0; i<100; i++){

 dom.style.left = i + 'px';

}      

浏覽器會進行100次DOM更新嗎?顯然不是的,這樣太耗性能了。事實上,這100次for循環同屬一個task,浏覽器隻在該task執行完後進行一次DOM更新。

那我們的思路就來了:隻要讓nextTick裡的代碼放在UI render步驟後面執行,豈不就能通路到更新後的DOM了?

vue就是這樣的思路,并不是用MO進行DOM變動監聽,而是用隊列控制的方式達到目的。

以上就是vue的nextTick方法的實作原理了,總結一下就是:

  1. vue用異步隊列的方式來控制DOM更新和nextTick回調先後執行
  2. microtask因為其高優先級特性,能確定隊列中的微任務在一次事件循環前被執行完畢
  3. 因為相容性問題,vue不得不做了microtask向macrotask的降級方案