什麼是$nextTick?為什麼需要它?異步更新隊列有什麼好處?

有一個div,默認用 v-if 將它隱藏

,點擊一個按鈕後,改變 v-if 的值,①讓它顯示出來,②同時拿到這個div的文本內容。如果v-if的值是 false,直接去獲取div內容是獲取不到的,因為此時div還沒有被創建出來,那麼應該在點擊按鈕後,改變v-if的值為 true,div才會被創建,此時再去獲取,示例代碼如下:

什麼是$nextTick?為什麼需要它?異步更新隊列有什麼好處?

運行後在控制檯會拋出一個錯誤:Cannot read property 'innnerHTML of null,意思就是獲取不到div元素:

什麼是$nextTick?為什麼需要它?異步更新隊列有什麼好處?

這裡就涉及Vue一個重要的概念:異步更新隊列.

異步更新隊列

Vue在觀察到數據變化時並不是直接更新DOM,而是開啟一個隊列,並緩衝在同一個事件循環中發生的所數有據改變。在緩衝時會去除重複數據,從而避免不必要的計算和DOM操作。然後,在下一個事件循環tick中,Vue刷新隊列並執行實際(已去重的)工作。所以如果用一個for循環來動態改變數據100次,其實它只會應用最後1次改變,如果沒有這種機制,DOM就要重繪100次,這固然是一個很大的開銷。

異步更新隊列內部實現機制

Vue會根據當前瀏覽器環境優先使用原生的Promise.then

MutationObserver,如果都不支持,就會採用setTimeout代替。

知道了Vue異步更新DOM的原理,上面示例的報錯也就不難理解了。事實上,在執行this.showDiv = true時,div仍然還是沒有被創建出來,直到下一個vue事件循環時,才開始創建。$nextTick就是用來 '知道什麼時候DOM更新完成' 的,所以上面的示例代碼需要修改為,把DOM操作放在$nextTick()方法內,如下圖:

什麼是$nextTick?為什麼需要它?異步更新隊列有什麼好處?

這時再點擊事件,控制檯就打印出div的內容“這是一段文本“了:

什麼是$nextTick?為什麼需要它?異步更新隊列有什麼好處?


分享到:


相關文章: