首頁  >  文章  >  web前端  >  Vue3 Reactive響應式原理是什麼

Vue3 Reactive響應式原理是什麼

WBOY
WBOY轉載
2023-05-21 13:53:571056瀏覽

一、怎麼實現變數變化

怎麼實現變數變化,相關依賴的結果也跟著變化

Vue3 Reactive響應式原理是什麼

 當原本price=5變成price=20total應該變成40,但實際total並不會改變。解決方法可以這樣,當變數改變了,重新計算一次,那麼結果就會改變為最新的結果。

如果需要重新計算,我們需要將total語句儲存為一個函數,才能實現依賴的變數改變就進行一次依賴項計算。這裡就用effect表示函數名稱。

來,試試看:

Vue3 Reactive響應式原理是什麼

#實作了變數price改變,依賴變數price quantity的變數total也改變。

下一步,我們要解決的問題是:應該怎麼把effect儲存起來,讓程式碼更有通用性,而不是一直複寫effect,分開其他的功能的函數各司其職,也就是大家常說的解耦

二、怎麼實現變數變化

怎麼實現變數變化,變數改變後就取出effect執行

用什麼儲存effect呢?當然是用Set,因為Set會過濾出重複的元素,所以能夠保證儲存在Set中的函數不是重複的。這裡定義一個儲存effect依賴的變數為dep = new Set(),定義track函數表示儲存的過程。定義trigger函數用以取出dep中相關的effect函數執行(這裡定義的函數與Vue3原始碼同名同意義)。

  • #effect: 會影響結果的函數(要實作響應式的依賴語句)

  • track :儲存所有的effect

  • trigger: 當變數改變重新執行程式碼

Vue3 Reactive響應式原理是什麼

## ????,解耦之後程式碼結構更清晰了。

下面需要解決的一個問題:一個object通常有多個屬性,例如

product = { price: 5, quantity: 2 },在保存依賴時只創建了一個dep的集合,應該給pricequantity都創建dep,因為total的最終結果依賴這兩個屬性,其中任何一個改變都要觸發trigger函數。創建了兩個dep就需要一個容器將dep儲存起來。

三、將多個dep儲存在Map中

因為不同的屬性名稱有自己對應的

dep,所以我們用Map結構(鍵值對形式)來保存不同dep

Vue3 Reactive響應式原理是什麼

 ????,一個object的多個屬性依賴問題解決,更有通用性了。

下一個問題是:不可能只有一個對象,多個對象又怎麼辦?

let product = { price: 5, quantity: 2 } let user = { firstName: "Joe", lastName: "Smith" },例如兩個物件的時候就需要進一步修改上面的程式碼了。

四、將多個object的depsMap繼續儲存起來

這裡用

WeakMap資料結構去儲存多個需要響應式的object的depsMapWeakMap的基本使用和Map差不多,只不過WeakMap只接受物件為鍵值,而depsMap是一個Map 結構剛好(必須是)是物件類型。 targetMap作為儲存多個depsMap的容器名稱。

Vue3 Reactive響應式原理是什麼

????,到這裡已經基本實現了通用性的響應式程式碼了,但還有最後一個問題就是:我們的程式碼都需要手動執行(自己添加

trigger運行),不能自動運行。怎麼讓它能夠自動偵測變數改變,然後自動修改結果呢?

五、核心

透過Reflect和Proxy解決自執行問題

在JavaScript中,自動偵測變數不就是get、自動修改變數不就是set嗎?在Vue2.x版本中用ES5的Obeject.defineProperty()自帶的getter/setter去解決這個問題。 ES6中Proxy也能解決這個問題,但是Proxy不兼任IE瀏覽器,當時大家還討論過說不知道尤大怎麼去考慮這個問題,現在問題的答案就是——不考慮。也就是根本不考慮IE兼不相容????????。

Proxy就是代理的意思,任何對真實資料的操作它都能攔截並且代理操作,也就是說Object上一些能實現的方法,Proxy也能實現。 Proxy使用語法是new Proxy(target, hanler)handler是你想要實作什麼樣的代理程式配置。而Reflect就更神奇了,它的作用是取代Object類上的一些方法讓Obeject類別更純粹的代表一個類,不要附加太多方法在上面,例如a in obj表示判斷obj中是否有a,在Reflect中用Reflect.has( a)比較語意化的方式就可以取代先前的方法。

正是因為這樣,ProxyReflect就對應上了,都有Object上的方法。具體關於ReflectProxy的語法可以參考阮一峰大大的 ES6入門教程。

稍微封裝一下我們的函數,名叫Reactive

Vue3 Reactive響應式原理是什麼

# ????,至此,Vue3基本的回應式原理就解析完了。

六、原始碼解析(TypeScript)

Vue3 Reactive響應式原理是什麼

 returncreateReactiveObject函數,所以去看createReactiveObject

Vue3 Reactive響應式原理是什麼

 前面的程式碼都是判斷各種情況,我們就看最後幾行

const observed = new Proxy(
    target,
    collectionTypes.has(target.constructor) ? collectionHandlers : baseHandlers
  )

可以看到ProxyhandlercollectionHandlers或 baseHandlers,繼續選擇一個看一看。

在 baseHandlers中可以看到匯出了get/set/deleteProperty等屬性配置:

Vue3 Reactive響應式原理是什麼

我們來看看set

Vue3 Reactive響應式原理是什麼

#

以上是Vue3 Reactive響應式原理是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除