Vue 2.0 響應式數據的原理主要基于以下幾個關鍵點:
-
數據劫持與Object.defineProperty:
- Vue 2.0 使用
Object.defineProperty
方法來劫持對象的屬性,為其添加 getter 和 setter 方法。當數據被訪問或修改時,這些 getter 和 setter 方法會被觸發。 - 當 Vue 實例初始化時,它會遍歷 data 對象中的每一個屬性,并使用
Object.defineProperty
將它們轉化為 getter/setter,從而實現對數據的劫持。
- Vue 2.0 使用
-
依賴收集與Dep實例:
- 當一個屬性被訪問時(即 getter 被觸發),Vue 會創建一個 Dep 實例(依賴收集器),并將當前的 Watcher 實例(觀察者)添加到該 Dep 實例的訂閱者列表中。
- 這樣,Vue 就建立了屬性和依賴之間的關系,形成了一個響應式的數據依賴系統。
-
Watcher實例:
- Watcher 是 Vue 的一個核心組件,用于觀察和響應 Vue 實例上的數據變化。
- 當數據發生變化時(即 setter 被觸發),Dep 實例會通知所有訂閱的 Watcher 實例,Watcher 實例會重新計算并更新相應的視圖。
-
數組變更檢測:
- Vue 2.0 不能檢測到以下變動的數組:
- 當你利用索引直接設置一個項時,例如:
vm.items[indexOfItem] = newValue
- 當你修改數組的長度時,例如:
vm.items.length = newLength
- 當你利用索引直接設置一個項時,例如:
- 為了解決這些問題,Vue 提供了
Vue.set
和vm.$set
方法來確保這些變更能夠被檢測到。
- Vue 2.0 不能檢測到以下變動的數組:
-
發布-訂閱模式:
- Vue 的響應式系統實際上是一個典型的發布-訂閱模式。當數據發生變化時(發布事件),所有訂閱了該數據的 Watcher 實例都會收到通知(訂閱者收到事件),并觸發相應的更新操作。
-
異步更新隊列:
- Vue 在更新 DOM 時是異步執行的。當數據發生變化時,Vue 并不會立即更新 DOM,而是將更新操作放入一個隊列中,等到下一個“tick”(通常是下一個事件循環)才進行實際的 DOM 更新。這樣可以避免多次修改數據導致的頻繁 DOM 操作,從而提高性能。
歸納來說,Vue 2.0 的響應式數據原理是通過 Object.defineProperty
劫持對象的屬性,利用 Dep 和 Watcher 實例建立屬性和依賴之間的關系,并使用發布-訂閱模式來通知依賴進行更新操作。同時,Vue 通過異步更新隊列來優化 DOM 操作的性能。