欧美亚洲综合图区在线|天天射天天干国产成卜|99久久免费国产精精品|国产的欧美一区二区三区|日韩中文字幕无码不卡专区|亚麻成人aV极品一区二区|国产成人AV区一区二区三|成人免费一区二区三区视频网站

當(dāng)前位置:首頁 > 軟件開放 > 正文內(nèi)容

vue3響應(yīng)式(vue3響應(yīng)式原理)

軟件開放2年前 (2023-02-28)1297

今天給各位分享vue3響應(yīng)式的知識,其中也會對vue3響應(yīng)式原理進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!

本文目錄一覽:

vue3響應(yīng)式數(shù)據(jù)原理

Effect 原理解析 與 實(shí)現(xiàn)

引言:

vue、react 框架的核心都是數(shù)據(jù)驅(qū)動視圖也就是model = view,實(shí)現(xiàn)的核心也就是 數(shù)據(jù)響應(yīng)。

主要就三步:

一、effect:副作用函數(shù)

1.類似于vue2.0中watch 的升級版,如果函數(shù)中用到的響應(yīng)式的數(shù)據(jù)發(fā)生了變化,則會執(zhí)行該函數(shù)

二、proxy 與reflect

Object.defineProperty API 的一些缺點(diǎn):

vue3源碼的調(diào)試方法:

三、響應(yīng)式api reactive的實(shí)現(xiàn)

三、Effect的依賴收集與響應(yīng)觸發(fā) (分-總-分-問題)

手寫 Vue3 響應(yīng)式系統(tǒng):核心就一個數(shù)據(jù)結(jié)構(gòu)

響應(yīng)式是 Vue 的特色,如果你簡歷里寫了 Vue 項(xiàng)目,那基本都會問響應(yīng)式實(shí)現(xiàn)原理。

而且不只是 Vue,狀態(tài)管理庫 Mobx 也是基于響應(yīng)式實(shí)現(xiàn)的。

那響應(yīng)式是具體怎么實(shí)現(xiàn)的呢?

與其空談原理,不如讓我們來手寫一個簡易版吧。

響應(yīng)式

首先,什么是響應(yīng)式呢?

響應(yīng)式就是被觀察的數(shù)據(jù)變化的時候做一系列聯(lián)動處理。

就像一個 社會 熱點(diǎn)事件,當(dāng)它有消息更新的時候,各方媒體都會跟進(jìn)做相關(guān)報(bào)道。

這里 社會 熱點(diǎn)事件就是被觀察的目標(biāo)。

那在前端框架里,這個被觀察的目標(biāo)是什么呢?

很明顯,是狀態(tài)。

狀態(tài)一般是多個,會通過對象的方式來組織。所以,我們觀察狀態(tài)對象的每個 key 的變化,聯(lián)動做一系列處理就可以了。

我們要維護(hù)這樣的數(shù)據(jù)結(jié)構(gòu):

圖片

狀態(tài)對象的每個 key 都有關(guān)聯(lián)的一系列 effect 副作用函數(shù),也就是變化的時候聯(lián)動執(zhí)行的邏輯,通過 Set 來組織。

每個 key 都是這樣關(guān)聯(lián)了一系列 effect 函數(shù),那多個 key 就可以放到一個 Map 里維護(hù)。

這個 Map 是在對象存在的時候它就存在,對象銷毀的時候它也要跟著銷毀。(因?yàn)閷ο蠖紱]了自然也不需要維護(hù)每個 key 關(guān)聯(lián)的 effect 了)

而 WeakMap 正好就有這樣的特性,WeakMap 的 key 必須是一個對象,value 可以是任意數(shù)據(jù),key 的對象銷毀的時候,value 也會銷毀。

所以,響應(yīng)式的 Map 會用 WeakMap 來保存,key 為原對象。

這個數(shù)據(jù)結(jié)構(gòu)就是響應(yīng)式的核心數(shù)據(jù)結(jié)構(gòu)了。

比如這樣的狀態(tài)對象:

const obj = {

a: 1,

b: 2

}

它的響應(yīng)式數(shù)據(jù)結(jié)構(gòu)就是這樣的:

const depsMap = new Map();

const aDeps = new Set();

depsMap.set('a', aDeps);

const bDeps = new Set();

depsMap.set('b', bDeps);

const reactiveMap = new WeakMap()

reactiveMap.set(obj, depsMap);

創(chuàng)建出的數(shù)據(jù)結(jié)構(gòu)就是圖中的那個:

圖片

圖片

然后添加 deps 依賴,比如一個函數(shù)依賴了 a,那就要添加到 a 的 deps 集合里:

effect(() = {

console.log(obj.a);

});

也就是這樣:

const depsMap = reactiveMap.get(obj);

const aDeps = depsMap.get('a');

aDeps.add(該函數(shù));

這樣維護(hù) deps 功能上沒啥問題,但是難道要讓用戶手動添加 deps 么?

那不但會侵入業(yè)務(wù)代碼,而且還容易遺漏。

所以肯定不會讓用戶手動維護(hù) deps,而是要做自動的依賴收集。

那怎么自動收集依賴呢?

讀取狀態(tài)值的時候,就建立了和該狀態(tài)的依賴關(guān)系,所以很容易想到可以代理狀態(tài)的 get 來實(shí)現(xiàn)。

通過 Object.defineProperty 或者 Proxy 都可以:

const data = {

a: 1,

b: 2

}

let activeEffect

function effect(fn) {

activeEffect = fn

fn()

}

const reactiveMap = new WeakMap()

const obj = new Proxy(data, {

get(targetObj, key) {

let depsMap = reactiveMap.get(targetObj);

if (!depsMap) {

reactiveMap.set(targetObj, (depsMap = new Map()))

}

let deps = depsMap.get(key)

if (!deps) {

depsMap.set(key, (deps = new Set()))

}

deps.add(activeEffect)

return targetObj[key]

}

})

effect 會執(zhí)行傳入的回調(diào)函數(shù) fn,當(dāng)你在 fn 里讀取 obj.a 的時候,就會觸發(fā) get,會拿到對象的響應(yīng)式的 Map,從里面取出 a 對應(yīng)的 deps 集合,往里面添加當(dāng)前的 effect 函數(shù)。

這樣就完成了一次依賴收集。

當(dāng)你修改 obj.a 的時候,要通知所有的 deps,所以還要代理 set:

set(targetObj, key, newVal) {

targetObj[key] = newVal

const depsMap = reactiveMap.get(targetObj)

if (!depsMap) return

const effects = depsMap.get(key)

effects effects.forEach(fn = fn())

}

基本的響應(yīng)式完成了,我們測試一下:

圖片

打印了兩次,第一次是 1,第二次是 3。

effect 會先執(zhí)行一次傳入的回調(diào)函數(shù),觸發(fā) get 來收集依賴,這時候打印的 obj.a 是 1

然后當(dāng) obj.a 賦值為 3 后,會觸發(fā) set,執(zhí)行收集的依賴,這時候打印 obj.a 是 3

依賴也正確收集到了:

圖片

結(jié)果是對的,我們完成了基本的響應(yīng)式!

當(dāng)然,響應(yīng)式不會只有這么點(diǎn)代碼的,我們現(xiàn)在的實(shí)現(xiàn)還不完善,還有一些問題。

比如,如果代碼里有分支切換,上次執(zhí)行會依賴 obj.b 下次執(zhí)行又不依賴了,這時候是不是就有了無效的依賴?

這樣一段代碼:

const obj = {

a: 1,

b: 2

}

effect(() = {

console.log(obj.a ? obj.b : 'nothing');

});

obj.a = undefined;

obj.b = 3;

第一次執(zhí)行 effect 函數(shù),obj.a 是 1,這時候會走到第一個分支,又依賴了 obj.b。

把 obj.a 修改為 undefined,觸發(fā) set,執(zhí)行所有的依賴函數(shù),這時候走到分支二,不再依賴 obj.b。

把 obj.b 修改為 3,按理說這時候沒有依賴 b 的函數(shù)了,我們執(zhí)行試一下:

圖片

第一次打印 2 是對的,也就是走到了第一個分支,打印 obj.b

第二次打印 nothing 也是對的,這時候走到第二個分支。

但是第三次打印 nothing 就不對了,因?yàn)檫@時候 obj.b 已經(jīng)沒有依賴函數(shù)了,但是還是打印了。

打印看下 deps,會發(fā)現(xiàn) obj.b 的 deps 沒有清除

圖片

所以解決方案就是每次添加依賴前清空下上次的 deps。

怎么清空某個函數(shù)關(guān)聯(lián)的所有 deps 呢?

記錄下就好了。

我們改造下現(xiàn)有的 effect 函數(shù):

let activeEffect

function effect(fn) {

activeEffect = fn

fn()

}

記錄下這個 effect 函數(shù)被放到了哪些 deps 集合里。也就是:

let activeEffect

function effect(fn) {

const effectFn = () = {

activeEffect = effectFn

fn()

}

effectFn.deps = []

effectFn()

}

對之前的 fn 包一層,在函數(shù)上添加個 deps 數(shù)組來記錄被添加到哪些依賴集合里。

get 收集依賴的時候,也記錄一份到這里:

圖片

這樣下次再執(zhí)行這個 effect 函數(shù)的時候,就可以把這個 effect 函數(shù)從上次添加到的依賴集合里刪掉:

圖片

cleanup 實(shí)現(xiàn)如下:

function cleanup(effectFn) {

for (let i = 0; i effectFn.deps.length; i++) {

const deps = effectFn.deps[i]

deps.delete(effectFn)

}

effectFn.deps.length = 0

}

effectFn.deps 數(shù)組記錄了被添加到的 deps 集合,從中刪掉自己。

全刪完之后就把上次記錄的 deps 數(shù)組置空。

我們再來測試下:

圖片

無限循環(huán)打印了,什么鬼?

問題出現(xiàn)在這里:

圖片

set 的時候會執(zhí)行所有的當(dāng)前 key 的 deps 集合里的 effect 函數(shù)。

而我們執(zhí)行 effect 函數(shù)之前會把它從之前的 deps 集合中清掉:

圖片

執(zhí)行的時候又被添加到了 deps 集合。

這樣 delete 又 add,delete 又 add,所以就無限循環(huán)了。

解決的方式就是創(chuàng)建第二個 Set,只用于遍歷:

圖片

這樣就不會無限循環(huán)了。

再測試一次:

圖片

現(xiàn)在當(dāng) obj.a 賦值為 undefined 之后,再次執(zhí)行 effect 函數(shù),obj.b 的 deps 集合就被清空了,所以需改 obj.b 也不會打印啥。

看下現(xiàn)在的響應(yīng)式數(shù)據(jù)結(jié)構(gòu):

圖片

確實(shí),b 的 deps 集合被清空了。

那現(xiàn)在的響應(yīng)式實(shí)現(xiàn)是完善的了么?

也不是,還有一個問題:

如果 effect 嵌套了,那依賴還能正確的收集么?

首先講下為什么要支持 effect 嵌套,因?yàn)榻M件是可以嵌套的,而且組件里會寫 effect,那也就是 effect 嵌套了,所以必須支持嵌套。

我們嵌套下試試:

effect(() = {

console.log('effect1');

effect(() = {

console.log('effect2');

obj.b;

});

obj.a;

});

obj.a = 3;

按理說會打印一次 effect1、一次 effect2,這是最開始的那次執(zhí)行。

然后 obj.a 修改為 3 后,會觸發(fā)一次 effect1 的打印,執(zhí)行內(nèi)層 effect,又觸發(fā)一次 effect2 的打印。

也就是會打印 effect1、effect2、effect1、effect2。

我們測試下:

圖片

打印了 effect1、effet2 這是對的,但第三次打印的是 effect2,這說明 obj.a 修改后并沒有執(zhí)行外層函數(shù),而是執(zhí)行的內(nèi)層函數(shù)。

為什么呢?

看下這段代碼:

圖片

我們執(zhí)行 effect 的時候,會把它賦值給一個全局變量 activeEffect,然后后面收集依賴就用的這個。

當(dāng)嵌套 effect 的時候,內(nèi)層函數(shù)執(zhí)行后會修改 activeEffect 這樣收集到的依賴就不對了。

怎么辦呢?

嵌套的話加一個棧來記錄 effect 不就行了?

也就是這樣:

圖片

執(zhí)行 effect 函數(shù)前把當(dāng)前 effectFn 入棧,執(zhí)行完以后出棧,修改 activeEffect 為棧頂?shù)?effectFn。

這樣就保證了收集到的依賴是正確的。

這種思想的應(yīng)用還是很多的,需要保存和恢復(fù)上下文的時候,都是這樣加一個棧。

我們再測試一下:

圖片

現(xiàn)在的打印就對了。

至此,我們的響應(yīng)式系統(tǒng)就算比較完善了。

全部代碼如下:

const data = {

a: 1,

b: 2

}

let activeEffect

const effectStack = [];

function effect(fn) {

const effectFn = () = {

cleanup(effectFn)

activeEffect = effectFn

effectStack.push(effectFn);

fn()

effectStack.pop();

activeEffect = effectStack[effectStack.length - 1];

}

effectFn.deps = []

effectFn()

}

function cleanup(effectFn) {

for (let i = 0; i effectFn.deps.length; i++) {

const deps = effectFn.deps[i]

deps.delete(effectFn)

}

effectFn.deps.length = 0

}

const reactiveMap = new WeakMap()

const obj = new Proxy(data, {

get(targetObj, key) {

let depsMap = reactiveMap.get(targetObj)

if (!depsMap) {

reactiveMap.set(targetObj, (depsMap = new Map()))

}

let deps = depsMap.get(key)

if (!deps) {

depsMap.set(key, (deps = new Set()))

}

deps.add(activeEffect)

activeEffect.deps.push(deps);

return targetObj[key]

},

set(targetObj, key, newVal) {

targetObj[key] = newVal

const depsMap = reactiveMap.get(targetObj)

if (!depsMap) return

const effects = depsMap.get(key)

// effects effects.forEach(fn = fn())

const effectsToRun = new Set(effects);

effectsToRun.forEach(effectFn = effectFn());

}

})

總結(jié)

響應(yīng)式就是數(shù)據(jù)變化的時候做一系列聯(lián)動的處理。

核心是這樣一個數(shù)據(jù)結(jié)構(gòu):

圖片

最外層是 WeakMap,key 為對象,value 為響應(yīng)式的 Map。這樣當(dāng)對象銷毀時,Map 也會銷毀。

Map 里保存了每個 key 的依賴集合,用 Set 組織。

我們通過 Proxy 來完成自動的依賴收集,也就是添加 effect 到對應(yīng) key 的 deps 的集合里。set 的時候觸發(fā)所有的 effect 函數(shù)執(zhí)行。

這就是基本的響應(yīng)式系統(tǒng)。

但是還不夠完善,每次執(zhí)行 effect 前要從上次添加到的 deps 集合中刪掉它,然后重新收集依賴。這樣可以避免因?yàn)榉种袚Q產(chǎn)生的無效依賴。

并且執(zhí)行 deps 中的 effect 前要創(chuàng)建一個新的 Set 來執(zhí)行,避免 add、delete 循環(huán)起來。

此外,為了支持嵌套 effect,需要在執(zhí)行 effect 之前把它推到棧里,然后執(zhí)行完出棧。

解決了這幾個問題之后,就是一個完善的 Vue 響應(yīng)式系統(tǒng)了。

當(dāng)然,現(xiàn)在雖然功能是完善的,但是沒有實(shí)現(xiàn) computed、watch 等功能,之后再實(shí)現(xiàn)。

最后,再來看一下這個數(shù)據(jù)結(jié)構(gòu),理解了它就理解了 vue 響應(yīng)式的核心:

圖片

vue3源碼解讀--data響應(yīng)式的處理

目錄

????vue2源碼

????vue3源碼

示例

源碼

? ? 上一節(jié),我們已經(jīng)看到了組件被掛載到頁面的流程。但是忽略了對options的處理。vue2中是在組件init過程中就對配置項(xiàng)進(jìn)行了合并處理,vue3中是在組件創(chuàng)建即setupComponent中執(zhí)行applyOptions做的這個事情

? ? 經(jīng)過對組件實(shí)例的解析操作,最終拿到的dataOptions即我們實(shí)例中的data函數(shù)??梢钥吹?,在vue3已經(jīng)不允許根組件定義為對象了

? ? 顯然reactive即響應(yīng)式實(shí)現(xiàn)的關(guān)鍵,順著調(diào)用關(guān)系找到createReactiveObject函數(shù)。常聽人提起的Proxy赫然立于眼前

? ? proxy和Object.defineProperty差不多,都可以攔截對象的訪問和修改操作,那么接下來的重點(diǎn)就是看下它是如何做依賴收集和派發(fā)更新的即可

? ? 當(dāng)前targetType=1,使用baseHandlers做處理器,即createGetter函數(shù)。當(dāng)組件render過程中將會觸發(fā)msg的訪問執(zhí)行到此

? ? 可以看到,如果msg是一個對象,則會遞歸reactive。為什么要遞歸處理呢?proxy不是已經(jīng)把整個對象都代理到了嗎?

? ? 寫一個例子看一下

? ? ? ? 如果正常訪問,我沒有問題的,每次都可以正確的觸發(fā)get

? ? ? ? 如果是拿到返回值再進(jìn)行訪問的話,res.c就是無效的

? ? ????把第二個值也轉(zhuǎn)為Proxy后就可以了

? ? 回到正題,進(jìn)入track函數(shù)

? ? 在trackEffects中完成依賴收集

? ? 同樣的,當(dāng)set newValue時將執(zhí)行到createSetter。這將執(zhí)行trigger進(jìn)行更新派發(fā)

總結(jié)

? ? 拿到options的data--視情況(如對象遞歸執(zhí)行)進(jìn)行reactive化--在訪問時收集依賴(ReactiveEffect)--設(shè)置值時派發(fā)更新

? ? proxy.x相當(dāng)于讓activeEffect去訂閱data的change,proxy.x = y則相當(dāng)于data發(fā)布更新,通知activeEffect執(zhí)行componentUpdateFn? ? ? ? ? ? ?--觀察者模式

聊一聊 Vue3 中響應(yīng)式原理

Vue.js 3.0 "One Piece" 正式發(fā)布已經(jīng)有一段時間了,真可謂是千呼萬喚始出來?。?/p>

相比于 Vue2.x , Vue3.0 在新的版本中提供了更好的性能、更小的捆綁包體積、更好的 TypeScript 集成、用于處理大規(guī)模用例的新 API 。

在發(fā)布之前,尤大大就已經(jīng)聲明了響應(yīng)式方面將采用 Proxy 對于之前的 Object.defineProperty 進(jìn)行改寫。其主要目的就是彌補(bǔ) Object.defineProperty 自身的一些缺陷,例如無法檢測到對象屬性的新增或者刪除,不能監(jiān)聽數(shù)組的變化等。

而 Vue3 采用了新的 Proxy 實(shí)現(xiàn)數(shù)據(jù)讀取和設(shè)置攔截,不僅彌補(bǔ)了之前 Vue2 中 Object.defineProperty 的缺陷,同時也帶來了性能上的提升。

今天,我們就來盤一盤它,看看 Vue3 中響應(yīng)式是如何實(shí)現(xiàn)的。

The Proxy object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object. MDN

Proxy - 代理,顧名思義,就是在要訪問的對象之前增加一個中間層,這樣就不直接訪問對象,而是通過中間層做一個中轉(zhuǎn),通過操作代理對象,來實(shí)現(xiàn)修改目標(biāo)對象。

關(guān)于 Proxy 的更多的知識,可以參考我之前的一篇文章 —— 初探 Vue3.0 中的一大亮點(diǎn)——Proxy ! ,這里我就不在贅述。

Vue3 中響應(yīng)式核心方法就是 reactive 和 effect , 其中 reactive 方法是負(fù)責(zé)將數(shù)據(jù)變成響應(yīng)式, effect 方法的作用是根據(jù)數(shù)據(jù)變化去更新視圖或調(diào)用函數(shù),與 react 中的 useEffect 有點(diǎn)類似~

其大概用法如下:

默認(rèn)會執(zhí)行一次,打印 Hello , 之后更改了 data.name 的值后,會在觸發(fā)執(zhí)行一次,打印 World 。

我們先看看 reactive 方法的實(shí)現(xiàn)~

reactive.js

首先應(yīng)該明確,我們應(yīng)該導(dǎo)出一個 reactive 方法,該方法有一個參數(shù) target ,目的就是將 target 變成響應(yīng)式對象,因此返回值就是一個響應(yīng)式對象。

reactive 方法基本結(jié)構(gòu)就是如此,給定一個對象,返回一個響應(yīng)式對象。

其中 isObject 方法用于判斷是否是對象,不是對象不需要代理,直接返回即可。

reactive 方法的重點(diǎn)是 Proxy 的第二個參數(shù) handler ,它承載監(jiān)控對象變化,依賴收集,視圖更新等各項(xiàng)重大責(zé)任,我們重點(diǎn)來研究這個對象。

handler.js

在 Vue3 中 Proxy 的 handler 主要設(shè)置了 get , set , deleteProperty , has , ownKeys 這些屬性,即攔截了對象的讀取,設(shè)置,刪除, in 以及 Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法。

這里我們偷個懶,暫時就考慮 set 和 get 操作。

handler.get()

get 獲取屬性比較簡單,我們先來看看這個,這里我們用一個方法創(chuàng)建 getHanlder 。

這里推薦使用了 Reflect.get 而并非 target[key] 。

可以發(fā)現(xiàn), Vue3 是在取值的時候才去遞歸遍歷屬性的,而非 Vue2 中一開始就遞歸 data 給每個屬性添加 Watcher ,這也是 Vue3 性能提升之一。

handler.set()

同理 set 操作,我們也是用一個方法創(chuàng)建 setHandler 。

Reflect.set 會返回一個 Boolean 值,用于判斷屬性是否設(shè)置成功。

完事后將 handler 導(dǎo)出,然后在 reactive 中引入即可。

測試幾組對象貌似沒啥問題,其實(shí)是有一個坑,這個坑也跟數(shù)組有關(guān)。

如上例子,如果我們選擇代理數(shù)組,在 setHandler 中打印其 key 和 value 的話會得到 3 4 , length 4 這兩組值:

如果不作處理,那么會導(dǎo)致如果更新視圖的話,則會觸發(fā)兩次,這肯定是不允許的,因此,我們需要將區(qū)分新增和修改這兩種操作。

Vue3 中是通過判斷 target 是否存在該屬性來區(qū)分是新增還是修改操作,需要借助一個工具方法 —— hasOwnProperty 。

這里我們將上述的 createSetter 方法修改如下:

如此一來,我們調(diào) push 方法的時候,就只會觸發(fā)一次更新了,非常巧妙的避免了無意義的更新操作。

effect.js

光上述構(gòu)造響應(yīng)式對象并不能完成響應(yīng)式的操作,我們還需要一個非常重要的方法 effect ,它會在初始化執(zhí)行的時候存儲跟其有關(guān)的數(shù)據(jù)依賴,當(dāng)依賴數(shù)據(jù)發(fā)生變化的時候,則會再次觸發(fā) effect 傳遞的函數(shù)。

其基本雛形如下,入?yún)⑹且粋€函數(shù),還有個可選參數(shù) options 方便后面計(jì)算屬性等使用,暫時不考慮:

createReactiveEffect 就是為了將 fn 變成響應(yīng)式函數(shù),監(jiān)控?cái)?shù)據(jù)變化,執(zhí)行 fn 函數(shù),因此該函數(shù)是一個高階函數(shù)。

createReactiveEffect 將原來的 fn 轉(zhuǎn)變成一個 reactvieEffect , 并將當(dāng)前的 effect 掛到全局的 activeEffect 上,目的是為了一會與當(dāng)前所依賴的屬性做好對應(yīng)關(guān)系。

我們必須要將依賴屬性構(gòu)造成 { prop : [effect,effect] } 這種結(jié)構(gòu),才能保證依賴屬性變化的時候,依次去觸發(fā)與之相關(guān)的 effect ,因此,需要在 get 屬性的時候,做屬性的依賴收集,將屬性與 effect 關(guān)聯(lián)起來。

依賴收集 —— track

在獲取對象的屬性時,會觸發(fā) getHandler ,再次做屬性的依賴收集,即 Vue2 中的發(fā)布訂閱。

在 setHandler 中獲取屬性的時候,做一次 track(target, key) 操作。

整個 track 的數(shù)據(jù)結(jié)構(gòu)大概是這樣

目的就是將 target , key , effect 之間做好對應(yīng)的關(guān)系映射。

打印 targetMap 的結(jié)構(gòu)如下:

**觸發(fā)更新 —— trigger **

上述已經(jīng)完成了依賴收集,剩下就是監(jiān)控?cái)?shù)據(jù)變化,觸發(fā)更新操作,即在 setHandler 中添加 trigger 觸發(fā)操作。

這樣一來,獲取數(shù)據(jù)的時候通過 track 進(jìn)行依賴收集,更新數(shù)據(jù)的時候再通過 trigger 進(jìn)行更新,就完成了整個數(shù)據(jù)的響應(yīng)式操作。

再回頭看看我們先前提到的例子:

控制臺會依次打印 Hello ***** effect ***** 以及 World ***** effect ***** , 分別是首次渲染觸發(fā)跟更新數(shù)據(jù)重渲染觸發(fā),至此功能實(shí)現(xiàn)!

整體來說, Vue3 相比于 Vue2 在很多方面都做了調(diào)整,數(shù)據(jù)的響應(yīng)式只是冰山一角,但是可以看出尤大團(tuán)隊(duì)非常巧妙的利用了 Proxy 的特點(diǎn)以及 es6 的數(shù)據(jù)結(jié)構(gòu)和方法。另外, Composition API 的模式跟 React 在某些程度上有異曲同工之妙,這種設(shè)計(jì)模式讓我們在實(shí)際開發(fā)使用中更加的方法快捷,值得我們?nèi)W(xué)習(xí),加油!

最后附上倉庫地址 github ,歡迎各位大佬批評斧正~

vue3響應(yīng)式的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于vue3響應(yīng)式原理、vue3響應(yīng)式的信息別忘了在本站進(jìn)行查找喔。

掃描二維碼推送至手機(jī)訪問。

版權(quán)聲明:本文由飛速云SEO網(wǎng)絡(luò)優(yōu)化推廣發(fā)布,如需轉(zhuǎn)載請注明出處。

本文鏈接:http://landcheck.net/post/10359.html

標(biāo)簽: vue3響應(yīng)式js

“vue3響應(yīng)式(vue3響應(yīng)式原理)” 的相關(guān)文章

軟件開發(fā)技術(shù)文檔(軟件開發(fā)技術(shù)文檔下載)

軟件開發(fā)技術(shù)文檔(軟件開發(fā)技術(shù)文檔下載)

本篇文章給大家談?wù)勡浖_發(fā)技術(shù)文檔,以及軟件開發(fā)技術(shù)文檔下載對應(yīng)的知識點(diǎn),希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、請問軟件項(xiàng)目的技術(shù)開發(fā)文檔都要寫些什么呢,具體要求是什么呢,要寫多少文檔呢 2、軟件開發(fā)文檔包括哪些 3、軟件開發(fā)項(xiàng)目中,過程管理文檔都包括什么? 4、...

手機(jī)軟件開發(fā)教程(安卓手機(jī)軟件開發(fā)教程)

手機(jī)軟件開發(fā)教程(安卓手機(jī)軟件開發(fā)教程)

今天給各位分享手機(jī)軟件開發(fā)教程的知識,其中也會對安卓手機(jī)軟件開發(fā)教程進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、如何開發(fā)手機(jī)app 2、app是如何制作的,APP如何開發(fā)? 3、ios端的手機(jī)app開發(fā)要怎么做? 4、如何制作軟件app...

LOL手游怎么賣號(lol手游賣號吧)

LOL手游怎么賣號(lol手游賣號吧)

本篇文章給大家談?wù)凩OL手游怎么賣號,以及l(fā)ol手游賣號吧對應(yīng)的知識點(diǎn),希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、英雄聯(lián)盟手游賬號好賣么 2、請問lol手游怎么租號? 3、5173怎么賣LOL號?就是在提交賬號信息前要做什么?要解除什么?密碼要嗎?怎么弄啊 4、lol...

油猴屏蔽網(wǎng)頁廣告腳本(瀏覽器去廣告腳本)

油猴屏蔽網(wǎng)頁廣告腳本(瀏覽器去廣告腳本)

今天給各位分享油猴屏蔽網(wǎng)頁廣告腳本的知識,其中也會對瀏覽器去廣告腳本進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、油猴上腳本已啟動,點(diǎn)開學(xué)習(xí)通視頻卻沒自動跳過怎么回事 2、如何刪除網(wǎng)頁中殘余的油猴腳本? 3、安卓adguard用不了油猴腳本 4...

婚禮官網(wǎng)免費(fèi)源碼(婚禮網(wǎng)站模板)

婚禮官網(wǎng)免費(fèi)源碼(婚禮網(wǎng)站模板)

今天給各位分享婚禮官網(wǎng)免費(fèi)源碼的知識,其中也會對婚禮網(wǎng)站模板進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、2022年國內(nèi)景區(qū)婚禮怎么報(bào)名 2、如何查詢一個企業(yè)的官網(wǎng)頁面源代碼?如何設(shè)置關(guān)鍵字的優(yōu)化,線上 3、愛克絲文婚禮公司還在嗎 4、婚禮的電...

十大手游交易平臺排行榜dd373(十大可交易的手游平臺)

十大手游交易平臺排行榜dd373(十大可交易的手游平臺)

本篇文章給大家談?wù)勈笫钟谓灰灼脚_排行榜dd373,以及十大可交易的手游平臺對應(yīng)的知識點(diǎn),希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、手游在哪里交易 2、游戲交易平臺有哪些? 3、賣游戲賬號哪個平臺好? 4、手游交易平臺哪個好 5、游戲幣交易平臺哪個最好? 手游在...

钟祥市| 德钦县| 余江县| 长丰县| 元江| 北辰区| 成武县| 茌平县| 海盐县| 安西县| 田阳县| 株洲市| 孝感市| 萨嘎县| 乳山市| 南昌市| 柘荣县| 中宁县| 西充县| 屏山县| 高安市| 金秀| 凤庆县| 永嘉县| 思茅市| 开原市| 皮山县| 杭锦旗| 平凉市| 黔东| 内丘县| 青浦区| 定陶县| 盐山县| 牙克石市| 建瓯市| 独山县| 铁力市| 信宜市| 达州市| 贡觉县|