您好,登錄后才能下訂單哦!
今天小編給大家分享一下Vue3 Reactive響應式原理是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
怎么實現變量變化,相關依賴的結果也跟著變化
當原本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
。
????,一個object的多個屬性依賴問題解決,更具有通用性了。
下一個問題是:不可能只有一個對象,多個對象又怎么辦?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響應式原理是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。