let app = new Vue({ data: { text: "text", text2: "text2" } })
第一步:
使用observe函數對Vue中的data對象進行處理,使其可觀察(observable)。這一步的實質就是使用Object.defineProperty方法重寫data的屬性,重寫屬性特徵(主要指set和get兩個屬性特徵函數,從而在獲取屬性值和設置屬性值的時候插入額外的操做來實現視圖中跟隨數據變化):
瞭解Vue實例化過程作了什麼?下面能夠看出,Vue實例化的時候,會把傳入對象的data屬性傳遞給實例的_data屬性,同時,調用observe函數來處理_data也就是option.data。observe函數實質上就是使_data對象的全部屬性的set, get。javascript
class Vue { constructor(options) { this._data = options.data; observe(this._data); } }
observe函數具體的實現,其實就是遍歷_data中的全部屬性,調用defineProperty在set和get來注入取值和設置值時的額外操做。
其中,dep是一個數組,其中存放着依賴於當前屬性的觀察者列表,也就是屬性改變時要通知列表中的這些對象來更新數據。java
function observe(obj) { Object.keys(obj).forEach((key) => { defineReactive(obj, key, obj[key]); }) } // defineReactive函數 function defineReactive(obj, key, value) { const dep = []; Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: () => { // 讀取值時的額外操做,即綁定當前的觀察者到依賴列表中 dep.push(Dep.target); return value; }, set: (newVal) => { if (newVal === value) { return }; // 設置值時的額外操做,即設置值時通知依賴列表中的全部觀察者來更新數據 dep.forEach((a) => a.update); value = newVal; } }) }