天天看點

淺談Vue響應式原理

Vue.js 的核心包括一套“響應式系統”。

“響應式”,是指當資料改變後,Vue 會通知到使用該資料的代碼。例如,視圖渲染中使用了資料,資料改變後,視圖也會自動更新。

對于官網上關于響應式資料的描述,并不能讓人短時間内明白其原理。下面我将按照我的了解分析一下Vue2.0響應式核心代碼實作。

Vue中響應式資料分為:對象類型{}和數組類型[]

我們若想要實作響應式,需要以下類和方法:

資料data

資料監聽器defineReactive

訂閱者(更新視圖)watcher

維護訂閱者dep

狀态active

實作原理: 對象内部通過defineReactive方法,使用Object.defineProperty将屬性進行劫持(隻會劫持已經存在的屬性)。

假設頁面上有容器app,data存放響應式變量,當data中的值改變時,容器内的數值也會發生變化。

watcher所執行的操作 将頁面上的内容更新=>視圖更新

将data中的屬性依次增加get()和set()方法,這樣當使用者取值的時候,當作模版收集起來。待資料變化通知模版資料更新。

淺談Vue響應式原理

當定義watcher時,會依次執行(1)=>(2)=>(3)=>(4)。

每個屬性都擁有自己的dep屬性,存放它所存放的watcher,當屬性變化後會同志自己對應的watcher去更新。

Vue2.0響應式用的是Object.definePropertyVue3.0響應式用的是proxy

當data中的資料存在多層嵌套的時候,如果用Object.defineProperty,内部會進行遞歸,影響性能。proxy提升性能,但是不相容ie11。

數組考慮性能原因沒有用defineProperty對數組的每一項進行攔截,而是選擇對數組原型上的方法進行重寫(push,pop,shift,unshift,splice,sort,reverse)隻有這7種方法會重寫數組

在Vue中修改數組的索引和長度是無法監控到的。需要通過以上7種變異方法修改數組才會觸發數組對應的watcher進行更新。數組中如果是對象類型也會進行遞歸劫持。

如果想要更改索引,可以通過Vue.$set來進行處理,内部核心代碼是splice方法