原因:可以提升效能。如果不採用非同步更新,那麼每次更新資料都會對目前元件進行重新渲染;所以為了效能考慮,Vue會在本輪資料更新後,再去異步更新視圖,而不是每當有資料更新,就立即更新視圖。
本教學操作環境:windows7系統、vue3版,DELL G3電腦。
#nextTick確保我們所操作的DOM是更新之後的。
(1)套用場景:在視圖更新之後,基於新的視圖進行操作。
nextTick()
的回呼函數中。 nextTick()
的回調函數中。 nextTick
了。 (2)原理:
nextTick 是典型的將底層JS執行原理應用到具體案例中的範例,引入非同步更新佇列機制的原因∶
#如果不採用非同步更新,那麼每次更新資料都會對目前元件進行重新渲染。 所以為了效能考慮,Vue 會在本輪資料更新後,再去異步更新視圖。 而不是每當有資料更新,就立即更新視圖。
nextTick(callback)
;當你設定vm.someData = 'new value',DOM 不會馬上更新,而是在非同步佇列被清除,也就是下一個事件循環開始時執行更新才會進行必要的DOM更新。
(3) vue的降級策略
Vue 在內部對非同步佇列嘗試使用原生的Promise.then、MutationObserver 和setImmediate,如果執行環境不支持,則會採用setTimeout(fn, 0) 代替,進行降級處理。降級處理的目的都是將flushCallbacks
函數放入微任務或巨集任務佇列,等待下一次事件循環時來執行
實際刷新佇列是有可能在本次事件循環的微任務中刷新的,也可能是在下一個事件循環中刷新的。這取決於程式碼目前執行的環境,如若目前執行環境支援promise,那麼nextTick內部實際上會用Promise去執行,那麼佇列刷新就會在本次事件循環的微任務中去執行。
優先選擇微任務的原因:在微任務中更新佇列是會比在巨集任務中更新少一次UI渲染的。
vue是元件級更新,元件內有資料變化時,該元件就會更新。例:this.a = 1、this.b=2(同一個watcher)
(1)原因:如果不採用非同步更新,那麼每次更新資料都會對目前元件進行重新渲染。 所以為了效能考慮,Vue 會在本輪資料更新後,再去異步更新視圖。 而不是每當有資料更新,就立即更新視圖。
(2)過程:
#Vue是非同步執行dom更新的,一旦觀察到資料變化,Vue就會開啟一個佇列,然後把在同一個事件循環(event loop) 中觀察到資料變化的watcher 推送到這個佇列。
如果這個watcher被觸發多次,只會被推送到佇列一次。這種緩衝行為可以有效的去掉重複數據,避免不必要的計算和Dom操作。
而在下一個事件循環時,Vue會清空佇列,並進行必要的DOM更新。
3)原始碼解析:
資料變更時,透過notify通知watcher進行更新操作;
透過subs[i].update依序呼叫watcher的update(未更新視圖);
將watcher放到佇列中,在queueWatcher會根據watcher的id去重(多個屬性依賴一個watcher),如果佇列中沒有該watcher就會將該watcher新增至佇列(未更新視圖);
透過nextTick非同步執行flushSchedulerQueue方法刷新watcher佇列(更新視圖);
#
以上是vue為什麼是非同步渲染的詳細內容。更多資訊請關注PHP中文網其他相關文章!