天天看點

Vue.js實作響應式系統的基本原理

Vue.js 是一款 MVVM 架構,資料模型僅僅是普通的 JavaScript 對象,但是對這些對象進行操作時,卻能影響對應視圖,它的核心實作就是「響應式系統」。盡管我們在使用 Vue.js 進行開發時不會直接修改「響應式系統」,但是了解它的實作有助于避開一些常見的「坑」,也有助于在遇見一些琢磨不透的問題時可以深入其原理來解決它。

Object.defineProperty

首先我們來介紹一下

Object.defineProperty

,Vue.js就是基于它實作「響應式系統」的。Object.defineProperty()的作用就是直接在一個對象上定義一個新屬性,或者修改一個已經存在的屬性

實作

observer

(可觀察的)

知道了

Object.defineProperty

以後,我們來用它使對象變成可觀察的。在生成vue執行個體時,為對傳入的data進行周遊,使用Object.defineProperty把這些屬性轉為getter/setter。每個vue執行個體都有一個watcher執行個體,它會在執行個體渲染時記錄這些屬性,并在setter觸發時重新渲染。為了更加直覺的了解,下面是元件渲染時更新data的過程圖。在data進行改變時會調用内部的settter方法,在data進行擷取時,會調用内部的getter方法,如果一個處的data被改變了,那麼對象被Watcher發現後,就會渲染data,這樣就實作了某一處的資料改變,其他處調用此資料也相應發生改變。

Vue.js實作響應式系統的基本原理

說的更加直白一點就是,Vue()在

init

的時候通過

Object.defineProperty

進行了綁定,它使得當被設定的對象被讀取的時候會執行

getter

函數,而在當被指派的時候會執行

setter

函數。當 render function 被渲染的時候,因為會讀取所需對象的值,是以會觸發

getter

函數進行「依賴收集」,「依賴收集」的目的是将觀察者 Watcher 對象存放到目前閉包中的訂閱者 Dep 的 subs 中。在修改對象的值的時候,會觸發對應的

setter

setter

通知之前「依賴收集」得到的 Dep 中的每一個 Watcher,告訴它們自己的值改變了,需要重新渲染視圖。這時候這些 Watcher 就會開始調用

update

來更新視圖,這就是Vue.js實作響應式系統的基本原理。

vue