vue3.0-響應式原理-Proxy


1:什么是響應式❓

例子:let a = 1,b = 2;let c = a + b

conosle.log(c)  // => 3

這個時候需要觸發c 返回 結果

改變 a 的值 再次打印c 才會顯示結果

響應式就是改變a的值,c就會自動改變結果

2:js中如何實現響應式❓

  • 檢測其中某一個值是否發生變化
  • 用跟蹤(track)函數修改值
  • 用觸發(trigger)函數更新為最新的值

 

3:Vue是怎么實現響應式的?vue中如何跟蹤變化❓

vue中會用Object.defineProperty 的set,get方法處理遍歷所有的property並將其轉換為Proxy

為啥用Proxy?之前的不好嗎?

兩者的Surface Api 相同,但是Proxy 更簡單,同時提升了性能,代碼簡單它不香嗎?

 

提升了那些性能❓簡單了啥❓

Proxy 與 Object.defineProperty的對比  🤓

關於ES6代理性能的思考 🤓

 

為啥還要defineProperty,不直接用Proxy❓

為了支持IE瀏覽器!!

 

Proxy 到底是啥❓

Proxy 是一個包含另一個對象或函數並允許你對其進行攔截的對象。 (vue官方說法)
或者就叫代理Proxy對象用於創建一個對象的代理,從而實現基本操作的攔截和自定義(如屬性查找、賦值、枚舉、函數調用等)。(mdn說法)

 1 const dinner = {
 2   meal: 'tacos'
 3 }
 4 
 5 const handler = {
 6   get(target, prop) { // target源對象 prop 對象的key
 7     // 這里可以插一個攔截器
 8     return target[prop] // 返回對應的value
 9   }
10 }
11 
12 const proxy = new Proxy(dinner, handler)
13 console.log(proxy.meal)
14 
15 // tacos

 

 

Proxy提供了一個特性,不必這樣的返回target[prop],而是進一步使用Reflect方法。它允許我們正確的執行this綁定,比如

const dinner = {
  meal: 'tacos'
}

const handler = {
  get(target, prop, receiver) {
    // ...arguments  => {meal: "tacos"} "meal" Proxy {meal: "tacos"}
    return Reflect.get(...arguments)
  }
}

const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)  // tacos
console.log(proxy)  // Proxy {meal: "tacos"}

 

 

Reflect.get是啥❓

Reflect  是一個內置對象,它提供了攔截js 操作的方法
Reflect.get 獲取對象身上某個屬性的值,類似於 target[name]

 

Reflect.get(target, propertyKey[, receiver])

target需要取值的目標對象

propertyKey需要獲取的值的鍵值

receiver如果target對象中指定了getterreceiver則為getter調用時的this值。

我們之前提到過,為了有一個 API 能夠在某些內容發生變化時更新最終值,我們必須在內容發生變化時設置新的值。我們在處理器,一個名為 track 的函數中執行此操作,該函數可以傳入 target 和 key 兩個參數。

const dinner = {
  meal: 'tacos'
}

const handler = {
  get(target, prop, receiver) {
    track(target, prop) // 這個玩意就是上面提到的 用跟蹤(track)函數修改值
    return Reflect.get(...arguments)
  }
}

const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)

// tacos

 

 

現在跟蹤函數也好了,該觸發(trigger)函數了

當某些內容發生改變時我們會設置新的值。為此,我們將通過觸發這些更改來設置新 Proxy 的更改:

const dinner = {
  meal: 'tacos'
}

const handler = {
  get(target, prop, receiver) {
    track(target, prop) // 跟蹤 key修改了值
    return Reflect.get(...arguments)
  },
  set(target, key, value, receiver) {
    trigger(target, key) // 觸發了,去改 key 的value
    return Reflect.set(...arguments)
  }
}

const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)

// tacos

 

 

現在回頭看看

js中如何實現響應式的❓

  • 檢測其中某一個值是否發生變化
  • 用跟蹤(track)函數修改值
  • 用觸發(trigger)函數更新為最新的值

Vue就是這么干的

  • 當某個值發生變化時進行檢測:我們不再需要這樣做,因為 Proxy 允許我們攔截它
  • 跟蹤更改它的函數:我們在 Proxy 中的 getter 中執行此操作,稱為 effect
  • 觸發函數以便它可以更新最終值:我們在 Proxy 中的 setter 中進行該操作,名為 trigger


免責聲明!

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



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