Vue 2 的響應式原理主要基于 數據劫持 和 發布-訂閱模式,通過 Object.defineProperty
對對象的屬性進行攔截,實現數據的監控與視圖更新。具體原理如下:
1. 數據劫持:Object.defineProperty
Vue 2 在初始化過程中,通過 Object.defineProperty
給對象的每一個屬性添加 getter 和 setter,來劫持數據的訪問和修改。
- getter: 當訪問該屬性時,Vue 會觸發
getter
,在這個過程中 Vue 會將當前的 watcher(即視圖中的依賴)收集到該屬性的依賴列表中。這樣,當該屬性發生變化時,相關的視圖就能知道并做出更新。 - setter: 當修改該屬性的值時,Vue 會觸發
setter
,然后觸發依賴更新(通過通知 watcher 進行視圖的重新渲染)。
2. 依賴收集:Dep
和 Watcher
Vue 2 中使用了 Dep 和 Watcher 對象來實現依賴收集和視圖更新:
-
Dep: 每個數據屬性(通過
Object.defineProperty
劫持的屬性)都會有一個對應的Dep
對象,負責管理該屬性的所有依賴(即需要觀察該屬性的視圖、計算屬性等)。當該數據發生變化時,Dep
會通知所有依賴該屬性的 watcher 進行更新。 -
Watcher: 在 Vue 組件中,每個組件實例都對應著一個
Watcher
,它會監聽模板中使用到的響應式數據。Watcher
會在數據發生變化時進行相應的視圖更新。
3. 發布-訂閱模式
- 發布者: 數據對象通過
Object.defineProperty
攔截屬性的訪問和修改,作為發布者。 - 訂閱者: 視圖(
watcher
)和計算屬性等是訂閱者,它們會在數據變化時進行相應的更新。通過Dep
,每當數據發生變化時,Dep
會通知所有相關的watcher
,從而觸發視圖更新。
4. 視圖更新
當數據發生變化時,setter
會觸發 Dep
的通知機制,Dep
會遍歷所有依賴它的 watcher
,然后更新視圖。Vue 會通過 虛擬 DOM 比對前后差異(即 diff 算法),然后將差異應用到實際的 DOM 上,從而實現視圖的更新。
總結
- Vue 2 通過
Object.defineProperty
劫持數據的 getter 和 setter,來監聽數據的訪問和修改。 - 使用 Dep 和 Watcher 實現 依賴收集 和 視圖更新。
- 視圖變化時,
watcher
觸發更新,通過 虛擬 DOM 和 diff 算法 優化性能,最終更新真實 DOM。
Vue 2 的響應式系統基于數據劫持和發布-訂閱模式,提供了數據和視圖的雙向綁定機制,簡化了開發過程中的 DOM 操作。