Skip to content
On this page

Vue2 資料響應核心

說明

Vuemvvm 軟體架構 「畫面」與「資料」可以雙向綁定,就是基於 物件屬性定義 Object.defineProperty ,這也是 Vue2 雙向資料綁定的核心 API。

原理

Vue 實例中的 data 資料做「遍歷」,再將每個遍歷出來的數據項目,再用 物件屬性定義 Object.defineProperty 定義 gettersetter

圖片出處

  • getter 當資料被「讀取」時,會存入到 Watcher 進行收集。
  • setter 當資料被「修改」時,就會通知 Watcher 進行畫面更新渲染。

簡化例子

js
class Vue {
  constructor(options) {
    this._data = options.data
    observer(this._data)
  }
}

function observer(data) {
  if (!data || typeof data !== 'object') return false

  // 定義所有 data getter setter
  Object.keys(data).forEach((key) => {
    defineReactive(data, key, data[key])
  })
}

function defineReactive(obj, key, value) {
  Object.defineProperty(obj, key, {
    enumerable: true, // 可被枚舉
    configurable: true, // 可被修改與刪除
    get reactiveGetter() {
      return value
    },
    set reactiveSetter(newValue) {
      if (newValue === value) return false

      // cd 更新畫面核心功能
      cd(newValue)
    },
  })
}

提醒

這只是簡化後的說明,實際的響應原理是更複雜的。

DEMO

defineProperty 寫一個雙向綁定:

  • input 改變,更新資料
  • 資料改變,更新畫面

缺點

  • 若物件有新增屬性,必須要整個遍歷設置後,才能監聽。
  • 物件屬性如果很複雜,必須要深度遍歷才能監聽

Reference