1. 程式人生 > WINDOWS開發 >Vue2.X監聽data變化的核心API—Object.defineProperty詳解

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,{
        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,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