shallowReactive與reactive的原理淺析


vue3中的shallowReactive與reactive是怎么實現的呢?學習自尚硅谷

目的

使一個正常的object對象轉化為響應式對象

解決方案

簡單的說,就是w3c在object的增刪改查時增加了hook函數,可以讓用戶對原生js獲取事件、賦值事件等進行捕捉。這個hook函數就是ProxyReflect.
我接下來做的一件事就是使用這個hook函數,來使一個正常的object對象轉化為響應式對象。

嚴格來講,這個最后結果還不是響應式對象,只是這個object再增刪改查屬性的時候會觸發自定義邏輯,具體編寫什么樣的邏輯能能夠做到vue3中的響應式,本文沒有闡述。

可以首先定義一個事件處理函數,對原生js獲取事件、賦值事件等進行捕捉,隨后再傳遞給Reflect

const reactiveHandler = {
  get (target, key) {

    if (key==='_is_reactive') return true
    console.log('數據已獲取');

    return Reflect.get(target, key)
  },

  set (target, key, value) {
    const result = Reflect.set(target, key, value)
    console.log('數據已更新, 去更新界面')
    return result
  },

  deleteProperty (target, key) {
    const result = Reflect.deleteProperty(target, key)
    console.log('數據已刪除, 去更新界面')
    return result
  },
}

然后就可以進行轉化了:

/* 
自定義shallowReactive
目的是讓該對象成為一個Proxy對象,方便對一些增刪改查的方法進行攔截並添加自定義邏輯
*/
function shallowReactive(obj) {
  return new Proxy(obj, reactiveHandler)
}

/* 
自定義reactive
目的是讓該對象,以及該對象內部所有object類型的成員成為一個Proxy對象,方便對一些增刪改查的方法進行攔截並添加自定義邏輯
*/
function reactive (target) {
  if (target && typeof target==='object') {
    // 內部代碼塊的作用是:
      // 1. 遍歷子元素,目的是查看子元素中是否存在object,如果存在再次進入子元素;
      // 2. 最終返回一個代理對象Proxy,代理該object

    if (target instanceof Array) { 

      // 檢測到是數組
      target.forEach((item, index) => {
        target[index] = reactive(item)
      })

    } else { 

      // 檢測到是對象
      Object.keys(target).forEach(key => {
        target[key] = reactive(target[key])
      })

    }
    // 如果這個taraget是一個object,下面的代碼是無論如何都會對這個object執行的
    // 換句話說:對每一個子object類型的對象,執行了下面的代碼
    const proxy = new Proxy(target, reactiveHandler)
    return proxy
  }

  // 如果不是object,則直接返回
  return target
}







console.log('=================測試自定義shallowReactive');
const proxy = shallowReactive({
  a: {
    b: 3
  }
})

proxy.a = {b: 4} // 劫持到了
proxy.a.b = 5 // 沒有劫持到

console.log('=================測試自定義reactive');
/* 測試自定義reactive */
const obj = {
  a: 'abc',
  b: [{x: 1}],
  c: {x: [11]},
}

const proxy2 = reactive(obj)
console.log(proxy2)
proxy2.b[0].x += 1
proxy2.c.x[0] += 1


免責聲明!

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



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