怎麼實現變數變化,相關依賴的結果也跟著變化
當原本price=5
變成price=20
後total
應該變成40
,但實際total
並不會改變。解決方法可以這樣,當變數改變了,重新計算一次,那麼結果就會改變為最新的結果。
如果需要重新計算,我們需要將total
語句儲存為一個函數,才能實現依賴的變數改變就進行一次依賴項計算。這裡就用effect
表示函數名稱。
來,試試看:
#實作了變數price
改變,依賴變數price quantity
的變數total
也改變。
下一步,我們要解決的問題是:應該怎麼把effect
儲存起來,讓程式碼更有通用性,而不是一直複寫effect
,分開其他的功能的函數各司其職,也就是大家常說的解耦。
怎麼實現變數變化,變數改變後就取出effect執行
用什麼儲存effect
呢?當然是用Set,因為Set會過濾出重複的元素,所以能夠保證儲存在Set中的函數不是重複的。這裡定義一個儲存effect
依賴的變數為dep = new Set()
,定義track
函數表示儲存的過程。定義trigger
函數用以取出dep
中相關的effect
函數執行(這裡定義的函數與Vue3原始碼同名同意義)。
#effect
: 會影響結果的函數(要實作響應式的依賴語句)
track
:儲存所有的effect
trigger
: 當變數改變重新執行程式碼
## ????,解耦之後程式碼結構更清晰了。 下面需要解決的一個問題:一個object通常有多個屬性,例如
product = { price: 5, quantity: 2 },在保存依賴時只創建了一個
dep的集合,應該給
price和
quantity都創建
dep,因為
total的最終結果依賴這兩個屬性,其中任何一個改變都要觸發
trigger函數。創建了兩個
dep就需要一個容器將
dep儲存起來。
dep,所以我們用Map結構(鍵值對形式)來保存不同
dep。
let product = { price: 5, quantity: 2 }
let user = { firstName: "Joe", lastName: "Smith" },例如兩個物件的時候就需要進一步修改上面的程式碼了。
WeakMap資料結構去儲存多個需要響應式的object的
depsMap。
WeakMap的基本使用和
Map差不多,只不過
WeakMap只接受物件為鍵值,而
depsMap是一個
Map 結構剛好(必須是)是物件類型。
targetMap作為儲存多個
depsMap的容器名稱。
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)
比較語意化的方式就可以取代先前的方法。
正是因為這樣,Proxy
和Reflect
就對應上了,都有Object
上的方法。具體關於Reflect
和Proxy
的語法可以參考阮一峰大大的 ES6入門教程。
稍微封裝一下我們的函數,名叫Reactive
# ????,至此,Vue3基本的回應式原理就解析完了。
return
了createReactiveObject
函數,所以去看createReactiveObject
。
前面的程式碼都是判斷各種情況,我們就看最後幾行
const observed = new Proxy( target, collectionTypes.has(target.constructor) ? collectionHandlers : baseHandlers )
可以看到Proxy
的handler
為collectionHandlers
或 baseHandlers
,繼續選擇一個看一看。
在 baseHandlers
中可以看到匯出了get/set/deleteProperty
等屬性配置:
我們來看看set
:
以上是Vue3 Reactive響應式原理是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!