Vue.js 的核心包括一套“響應式系統”。
“響應式”,是指當資料改變後,Vue 會通知到使用該資料的代碼。例如,視圖渲染中使用了資料,資料改變後,視圖也會自動更新。
對于官網上關于響應式資料的描述,并不能讓人短時間内明白其原理。下面我将按照我的了解分析一下Vue2.0響應式核心代碼實作。
Vue中響應式資料分為:對象類型{}和數組類型[]
我們若想要實作響應式,需要以下類和方法:
資料data
資料監聽器defineReactive
訂閱者(更新視圖)watcher
維護訂閱者dep
狀态active
實作原理: 對象内部通過defineReactive方法,使用Object.defineProperty将屬性進行劫持(隻會劫持已經存在的屬性)。
假設頁面上有容器app,data存放響應式變量,當data中的值改變時,容器内的數值也會發生變化。
watcher所執行的操作 将頁面上的内容更新=>視圖更新
将data中的屬性依次增加get()和set()方法,這樣當使用者取值的時候,當作模版收集起來。待資料變化通知模版資料更新。
當定義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方法