Vue中數據掛載的底層原理是通過監聽數據的變化,然后將相應的變化渲染到頁面上去。這個過程中需要理解幾個概念和核心API:
Object.defineProperty() Observer Dep(Dependency) Watcher Vue Component
Object.defineProperty()是Javascript原生API,它可以在一個對象上定義一個新的屬性或修改一個已有的屬性,并且能夠控制該屬性值的讀取和賦值操作。在定義屬性時,需要指定該屬性的描述符。描述符里的getter和setter函數分別在讀取和賦值該屬性值時觸發。Vue基于這個API,實現了一個Observer模塊,可以監聽對象/數組數據的變化,并通過getter和setter來實現數據變化的監聽和通知。例如:
let obj = { foo: 1 } Object.defineProperty(obj, 'bar', { get() { return this.foo + 1 }, set(newValue) { this.foo = newValue - 1 } }) console.log(obj.foo) // 1 console.log(obj.bar) // 2 obj.bar = 4 console.log(obj.foo) // 3
Observer模塊在Vue中扮演著關鍵的角色,使用Object.defineProperty()來實現數據變化的監聽和觸發響應。Observer模塊會遍歷目標對象(或數組)的每個屬性,并通過getter和setter來劫持這些屬性的讀取和寫入操作,從而能夠追蹤到數據的變化。Observer模塊中每個被劫持屬性都會有一個Dep對象,該對象維護著當前屬性相關的所有Watcher。在屬性值變化時,Dep對象會通知所有Watcher更新視圖。
Watcher對象是Vue中另一個核心概念,它用來描述一個觀察者(即訂閱者),能夠從Observer中監聽對象/數組數據的變化。Watcher對象內部實現了一個update方法,當Watcher監聽到數據變化時,它會調用update方法,通知Vue更新視圖。其中,Update方法做的事情就是調用Vue的渲染方法。
Vue的數據掛載是和Component緊密相連的。每個組件實例都有自己的Watcher集合,同時允許在自己內部使用數據和計算屬性。當一個組件實例的數據被修改時,相應的Watcher會自動通知組件重新渲染視圖。因為Vue的渲染方法是由Watcher來調用的,所以組件重渲染的時候,Watcher會自動創建和銷毀。這個過程中,每個Watcher都會綁定到相應的Dep對象上,并且會監聽到Dep對象的變化,從而觸發組件的重新渲染。