溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue3?Reactive響應(yīng)式原理是什么

發(fā)布時(shí)間:2022-07-04 09:32:50 來(lái)源:億速云 閱讀:200 作者:iii 欄目:開(kāi)發(fā)技術(shù)

今天小編給大家分享一下Vue3 Reactive響應(yīng)式原理是什么的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

一、怎么實(shí)現(xiàn)變量變化

怎么實(shí)現(xiàn)變量變化,相關(guān)依賴的結(jié)果也跟著變化

Vue3?Reactive響應(yīng)式原理是什么

 當(dāng)原本price=5變?yōu)?code>price=20后total應(yīng)該變?yōu)?code>40,但是實(shí)際total并不會(huì)改變。 解決辦法可以這樣,當(dāng)變量改變了,重新計(jì)算一次,那么結(jié)果就會(huì)改變?yōu)樽钚碌慕Y(jié)果。

如果需要重新計(jì)算,我們需要將total語(yǔ)句存儲(chǔ)為一個(gè)函數(shù),才能實(shí)現(xiàn)依賴的變量改變就進(jìn)行一次依賴項(xiàng)計(jì)算。這里就用effect表示函數(shù)名。

來(lái),試一下:

Vue3?Reactive響應(yīng)式原理是什么

實(shí)現(xiàn)了變量price改變,依賴變量price quantity的變量total也發(fā)生改變。

下一步,我們要解決的問(wèn)題是:應(yīng)該怎么把effect存儲(chǔ)起來(lái),讓代碼更加有通用性,而不是一直復(fù)寫effect,分離出其他的功能的函數(shù)各司其職,也就是大家常說(shuō)的解耦。

二、怎么實(shí)現(xiàn)變量變化

怎么實(shí)現(xiàn)變量變化,變量改變后就取出effect執(zhí)行

用什么存儲(chǔ)effect呢?當(dāng)然是用Set,因?yàn)镾et會(huì)過(guò)濾出重復(fù)的元素,所以能夠保證存儲(chǔ)在Set中的函數(shù)不是重復(fù)的。 這里定義一個(gè)存儲(chǔ)effect依賴的變量為dep = new Set(),定義track函數(shù)表示存儲(chǔ)的過(guò)程。 定義trigger函數(shù)用以取出dep中相關(guān)的effect函數(shù)執(zhí)行(這里定義的函數(shù)與Vue3源碼同名同意義)。

  • effect: 會(huì)影響結(jié)果的函數(shù)(要實(shí)現(xiàn)響應(yīng)式的依賴語(yǔ)句)

  • track:保存所有的effect

  • trigger: 當(dāng)變量改變重新執(zhí)行代碼

Vue3?Reactive響應(yīng)式原理是什么

 ????,解耦之后代碼結(jié)構(gòu)更清晰了。

下面需要解決的一個(gè)問(wèn)題:一個(gè)object通常有多個(gè)屬性,比如product = { price: 5, quantity: 2 },在保存依賴時(shí)只創(chuàng)建了一個(gè)dep的集合,應(yīng)該給pricequantity都創(chuàng)建dep,因?yàn)?code>total的最終結(jié)果依賴這兩個(gè)屬性,其中任何一個(gè)改變都要觸發(fā)trigger函數(shù)。創(chuàng)建了兩個(gè)dep就需要一個(gè)容器將dep存儲(chǔ)起來(lái)。

三、將多個(gè)dep存儲(chǔ)在Map中

因?yàn)椴煌膶傩悦凶约簩?duì)應(yīng)的dep,所以我們用Map結(jié)構(gòu)(鍵值對(duì)形式)來(lái)保存不同dep

Vue3?Reactive響應(yīng)式原理是什么

 ????,一個(gè)object的多個(gè)屬性依賴問(wèn)題解決,更具有通用性了。

下一個(gè)問(wèn)題是:不可能只有一個(gè)對(duì)象,多個(gè)對(duì)象又怎么辦?let product = { price: 5, quantity: 2 } let user = { firstName: "Joe", lastName: "Smith" },比如兩個(gè)對(duì)象的時(shí)候就需要進(jìn)一步修改上面的代碼了。

四、將多個(gè)object的depsMap繼續(xù)存儲(chǔ)起來(lái)

這里用WeakMap數(shù)據(jù)結(jié)構(gòu)去存儲(chǔ)多個(gè)需要響應(yīng)式的object的depsMap。WeakMap的基本使用和Map差不多,只不過(guò)WeakMap只接受對(duì)象為鍵值,而depsMap是一個(gè)Map結(jié)構(gòu)剛好(必須是)是對(duì)象類型。targetMap作為存儲(chǔ)多個(gè)depsMap的容器名。

Vue3?Reactive響應(yīng)式原理是什么

????,到這里已經(jīng)基本實(shí)現(xiàn)了通用性的響應(yīng)式代碼了,但是還有最后一個(gè)問(wèn)題就是:我們的代碼都需要手動(dòng)執(zhí)行(自己添加trigger運(yùn)行),不能自動(dòng)運(yùn)行。怎么讓它能夠自動(dòng)檢測(cè)變量改變,然后自動(dòng)修改結(jié)果呢?

五、核心

通過(guò)Reflect和Proxy解決自執(zhí)行問(wèn)題

在JavaScript中,自動(dòng)檢測(cè)變量不就是get、自動(dòng)修改變量不就是set嗎?在Vue2.x版本中用ES5的Obeject.defineProperty()自帶的getter/setter去解決這個(gè)問(wèn)題。ES6中Proxy也能解決這個(gè)問(wèn)題,但是Proxy不兼任IE瀏覽器,當(dāng)時(shí)大家還討論過(guò)說(shuō)不知道尤大怎么去考慮這個(gè)問(wèn)題,現(xiàn)在問(wèn)題的答案就是——不考慮。也就是根本不考慮IE兼不兼容????????。

Proxy就是代理的意思,任何對(duì)真實(shí)數(shù)據(jù)的操作它都能攔截并且代理操作,也就是說(shuō)Object上一些能實(shí)現(xiàn)的方法,Proxy也能實(shí)現(xiàn)。Proxy使用語(yǔ)法是new Proxy(target, hanler),handler是你想實(shí)現(xiàn)什么樣的代理功能配置。 而Reflect就更神奇了,它的作用是取代Object類上的一些方法讓Obeject類更純粹的代表一個(gè)類,不要附加太多方法在上面,比如a in obj表示判斷obj中是否有a,在Reflect中用Reflect.has(a)比較語(yǔ)義化的方式就可以代替之前的方法。

正是因?yàn)檫@樣,ProxyReflect就對(duì)應(yīng)上了,都有Object上的方法。 具體關(guān)于ReflectProxy的語(yǔ)法可以參考阮一峰大大的 ES6入門教程。

稍微封裝一下我們的函數(shù),名叫Reactive

Vue3?Reactive響應(yīng)式原理是什么

 ????,至此,Vue3基本的響應(yīng)式原理就解析完了。

六、源碼解析(TypeScript)

Vue3?Reactive響應(yīng)式原理是什么

 returncreateReactiveObject函數(shù),所以去看createReactiveObject

Vue3?Reactive響應(yīng)式原理是什么

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

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

可以看到ProxyhandlercollectionHandlers或者 baseHandlers,繼續(xù)選擇一個(gè)看一看。

在 baseHandlers中可以看到導(dǎo)出了get/set/deleteProperty等屬性配置:

Vue3?Reactive響應(yīng)式原理是什么

我們看一下set

Vue3?Reactive響應(yīng)式原理是什么

以上就是“Vue3 Reactive響應(yīng)式原理是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI