Vue2.X監聽data變化的核心API—Object.defineProperty詳解
阿新 • • 發佈:2020-04-13
Vue2.X監聽data變化的核心API—Object.defineProperty基本使用:
Object.defineProperty實現響應式
1.監聽物件(簡單物件)
上面通過監聽get,set方法瞭解到data變化,進而可以達到響應式。
2.複雜物件(深度監聽),深度監聽
觸發更新檢視// 觸發更新檢視 function updateView() { console.log(‘檢視更新‘) }
在上面例子data加:
// 準備資料 const data = { name: ‘佩奇‘,age: 20,info: { address:‘寧波‘ // 需要深度監聽 },}
// 重新定義屬性,監聽起來 function defineReactive(target,key,value) { // 核心 API Object.defineProperty(target,{ get() { return value },set(newValue) { if (newValue !== value) { // 設定新值 // 注意,value 一直在閉包中,此處設定完之後,再 get 時也是會獲取最新的值value = newValue // 觸發更新檢視 updateView() } } }) } // 監聽物件屬性 function observer(target) { if (typeof target !== ‘object‘ || target === null) { // 不是物件或陣列 return target } // 重新定義各個屬性(for in 也可以遍歷陣列) for (let key intarget) { defineReactive(target,target[key]) } }
// 監聽資料 observer(data)
此時我們在上面例子程式碼,沒有監聽到。
此時優化一下,在defineReactive方法里加一層監聽。
// 重新定義屬性,監聽起來 function defineReactive(target,value) { // 深度監聽 observer(value) // 核心 API Object.defineProperty(target,set(newValue) { if (newValue !== value) { // 設定新值 // 注意,value 一直在閉包中,此處設定完之後,再 get 時也是會獲取最新的值 value = newValue // 觸發更新檢視 updateView() } } }) }
可以深度監聽到了。
上面二例子, data.age = {num:21} 可以監聽到 而data.age.num = 22 卻沒有監聽到。
此時優化一下,在defineReactive方法中Object.defineProperty裡set方法加深度監聽observer(newValue)加一層監聽。
// 重新定義屬性,監聽起來 function defineReactive(target,value) { // 深度監聽 observer(value) // 核心 API Object.defineProperty(target,set(newValue) { if (newValue !== value) { // 深度監聽 observer(newValue) // 設定新值 // 注意,value 一直在閉包中,此處設定完之後,再 get 時也是會獲取最新的值 value = newValue // 觸發更新檢視 updateView() } } }) }
監聽陣列:
3.幾個缺點
1.深度監聽,需要遞迴到底,一次性計算量大(通過上面的例子)
2.新增屬性,監聽不到——所以有Vue.set
3.刪除屬性,監聽不到——所有已Vue.delete