Vue2.X監聽data變化的核心API—Object.defineProperty詳解


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, key, {
        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 in target) {
        defineReactive(target, key, target[key])
    }
}
// 監聽數據
observer(data)

 

 

 

 

此時我們在上面例子代碼,沒有監聽到。

 

 
          

 

 

此時優化一下,在defineReactive方法里加一層監聽。

// 重新定義屬性,監聽起來
function defineReactive(target, key, value) {
    // 深度監聽
    observer(value)
    // 核心 API
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        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, key, value) {
    // 深度監聽
    observer(value)

    // 核心 API
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if (newValue !== value) {
                 // 深度監聽
                 observer(newValue)

                // 設置新值
                // 注意,value 一直在閉包中,此處設置完之后,再 get 時也是會獲取最新的值
                value = newValue

                // 觸發更新視圖
                updateView()
            }
        }
    })
}

 

 

  監聽數組:

 

 

 

3.幾個缺點

1.深度監聽,需要遞歸到底,一次性計算量大(通過上面的例子)
2.
新增屬性,監聽不到 —— 所以有 Vue.set

3.刪除屬性,監聽不到 —— 所有已 Vue.delete

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM