1. 程式人生 > >vue1 & vue2 數據驅動更新視圖機制對比

vue1 & vue2 數據驅動更新視圖機制對比

直接 關系 依賴 vnode 數組 binding bind 循環 指令

vue1 小粒度更新,精確追蹤到數據變化所影響的dom變化,精確更新變化的dom

具體實現為,維護 observer watcher directive 三個類

·observer負責監聽數據變化,並派發事件,向上層傳播事件,維護一個watcher數組

·watcher訂閱observer,數據變化時執行事件,包括$watch註冊的回調函數和視圖更新

·directive負責建立數據data到dom對象的對應關系,對不同指令應用不同的更新方法,是watcher的其中一種類型

·parser 解析類似user.name user[0] user["name"] 這樣的expression,轉換為最終可查找到屬性的路徑

ps. 以上思路是簡化版,直接把observer按數據層級關系組織。而源碼中是單獨用了一個binding類來組織watcher的層級關系的(可能因為避免循環引用)。事件觸發後,在observer中傳播到頂層獲得一個變化數據的key(比如user.name.abc),再用這個路徑從binding的根開始定位到對應的user.name.abc,watcher存放在這個binding對象中。在這種策略中,只有最頂層的observer被監聽了,子observer只負責把事件傳播到頂層而已。

參考:https://github.com/youngwind/blog/issues/87

vue2 以組件粒度為範圍,組件內diff式更新,組件層面還是按vue1的方式更新

具體區別體現在,每個組件有了render函數,數據變化時只通知到組件更新,組件更新時會重建全部vnode樹,而不是精確更新了(當然到dom層面時還是會做diff,同樣表現為精確更新)

好處有:1.render函數可以用js寫組件,更靈活

2.跨平臺,vue1模板渲染方式依賴瀏覽器先解析vue模板

3.如果要建立精確的數據--dom對應關系,需要占用大量內存維護directive,vue2可以節約這部分內存

4.小粒度更新需要維護一個隊列(當數據重復變化時)來避免不必要的操作,vue2不要維護這部分

vue1 & vue2 數據驅動更新視圖機制對比