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

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

vue3響應(yīng)式原理代理與反射(vue3 響應(yīng)式原理)

軟件開(kāi)放2年前 (2023-01-18)1189

本篇文章給大家談?wù)剉ue3響應(yīng)式原理代理與反射,以及vue3 響應(yīng)式原理對(duì)應(yīng)的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站喔。

本文目錄一覽:

【手把手教你搓Vue響應(yīng)式原理】(一)初識(shí)Vue響應(yīng)式

在講這個(gè)之前,首先要明白一點(diǎn),這個(gè)所謂的響應(yīng)式,其實(shí)本身就是對(duì) MVVM 的理解。

MVVM 其實(shí)就是所謂的 Modal View ViewModal 。

簡(jiǎn)單理解,就是你的 data 中的數(shù)據(jù),和 template 模板中的界面,本身就是兩個(gè)東西。

但是, Vue 給你做了一層中間的 ViewModal ,讓視圖上的改變能反映到 data 中, data 中的改變能反映到視圖上。

在這個(gè)反映過(guò)程中,ViewModal就是視圖和數(shù)據(jù)的一個(gè)橋梁。

同樣是讓 a + 1 。

在 Vue 中,這個(gè)橋梁是你看不見(jiàn)的,因?yàn)? Vue 都幫你完成了視圖和數(shù)據(jù)的變化傳遞。

而 React 就是侵入式的,因?yàn)橐@式地聲明 setState ,通過(guò)它,來(lái)設(shè)置變量的同時(shí),設(shè)置視圖的改變。

所以,所謂的侵入式,其實(shí)就是對(duì)于橋梁的侵入。

所以, Vue 的神奇之處就在于,不需要我們手動(dòng)地顯示調(diào)用 setState ,也就是這個(gè)橋梁, Vue 已經(jīng)幫我們橋接上了。

要讓 data 改變的同時(shí),視圖也發(fā)生改變,所以,問(wèn)題的所在,就是我們需要監(jiān)聽(tīng),什么時(shí)候,這個(gè)變量發(fā)生了變量。

然而, ES5 中,就有那么一個(gè)特性,可以做到對(duì)于數(shù)據(jù)的劫持(監(jiān)聽(tīng))。

它就是 Object.defineProperty 。

Object.defineProperty( obj, prop, descriptor ) 方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性,并返回此對(duì)象,與此同時(shí),它可以對(duì) 對(duì)象的一些額外底層的屬性進(jìn)行設(shè)置 。例如可以設(shè)置 writable , enumerable , configurable 等屬性。

后面的額外屬性設(shè)置,才是我們使用它的重點(diǎn)。

但是,我們使用的不是上面的幾個(gè)屬性,最主要的還是它的 get set ,可以對(duì)屬性值的獲取和設(shè)置操作進(jìn)行攔截。

get主要是可以對(duì)值的獲取進(jìn)行攔截,,它必須要傳入一個(gè) return ,并且, 該函數(shù)的返回值會(huì)被用作屬性的值 。我們可以來(lái)看一個(gè)例子:

由于設(shè)置了 get ,所以,輸出 a.name 的時(shí)候直接會(huì)被攔截,走 get() 中的 return 所以,此時(shí), a.name 的值應(yīng)該是 你已經(jīng)被攔截了!。

set主要是可以對(duì)值的設(shè)置進(jìn)行攔截,該方法會(huì)接受一個(gè)參數(shù),那就是 被賦予的新值 。我們可以來(lái)看一個(gè)例子:

由于設(shè)置了 set ,所以,設(shè)置值的時(shí)候會(huì)被攔截,走 set() 中的方法。

所以, Vue 能自動(dòng)獲取data中的改變,反映到視圖的原因,就是有對(duì)于變量的獲取和設(shè)置的劫持,當(dāng)變量發(fā)生改變的同時(shí), Vue 能在第一時(shí)間知道,并且對(duì)視圖做出相應(yīng)的改變操作。

而這把鑰匙就是 Object.defineProperty 。

【尚硅谷】Vue源碼解析之?dāng)?shù)據(jù)響應(yīng)式原理

Object.defineProperty() - MDN

Proxy(vue響應(yīng)式原理:數(shù)據(jù)偵測(cè)--數(shù)據(jù)劫持和數(shù)據(jù)代理)

Object.defineProperty : 通過(guò)設(shè)定對(duì)象屬性getter/setter方法來(lái)監(jiān)聽(tīng)數(shù)據(jù)的變化,同時(shí)getter也用于依賴收集,而setter在數(shù)據(jù)變更時(shí)通知訂閱者更新視圖。

1.無(wú)法檢測(cè)到對(duì)象屬性的新增或刪除

由于js的動(dòng)態(tài)性,可以為對(duì)象追加新的屬性或者刪除其中某個(gè)屬性,這點(diǎn)對(duì)經(jīng)過(guò)Object.defineProperty方法建立的響應(yīng)式對(duì)象來(lái)說(shuō),只能追蹤對(duì)象已有數(shù)據(jù)是否被修改,無(wú)法追蹤新增屬性和刪除屬性,這就需要另外處理。

2.不能監(jiān)聽(tīng)數(shù)組的變化

vue在實(shí)現(xiàn)數(shù)組的響應(yīng)式時(shí),它使用了一些hack,把無(wú)法監(jiān)聽(tīng)數(shù)組的情況通過(guò)重寫數(shù)組的部分方法來(lái)實(shí)現(xiàn)響應(yīng)式,這也只限制在數(shù)組的push/pop/shift/unshift/splice/sort/reverse七個(gè)方法,其他數(shù)組方法及數(shù)組的使用則無(wú)法檢測(cè)到。

Proxy,字面意思是代理,是ES6提供的一個(gè)新的API,用于修改某些操作的默認(rèn)行為,可以理解為在目標(biāo)對(duì)象之前做一層攔截,外部所有的訪問(wèn)都必須通過(guò)這層攔截,通過(guò)這層攔截可以做很多事情,比如對(duì)數(shù)據(jù)進(jìn)行過(guò)濾、修改或者收集信息之類。借用 proxy的巧用 的一幅圖,它很形象的表達(dá)了Proxy的作用。

ES6原生提供的Proxy構(gòu)造函數(shù),用法如下:

其中obj為Proxy要攔截的對(duì)象,handler用來(lái)定制攔截的操作,返回一個(gè)新的代理對(duì)象proxy;Proxy代理特點(diǎn):

1.Proxy的代理針對(duì)的是整個(gè)對(duì)象,而不是像Object.defineProperty針對(duì)某個(gè)屬性。只需做一層代理就可以監(jiān)聽(tīng)同級(jí)結(jié)構(gòu)下的所有屬性變化,包括新增屬性和刪除屬性

2.Proxy也可以監(jiān)聽(tīng)數(shù)組的變化

參考:

能說(shuō)說(shuō)vue的響應(yīng)式原理嗎?

Vue 是一個(gè) MVVM 框架,核心是雙向數(shù)據(jù)綁定,VM(視圖模型)是作為 V(視圖) 和 M(模型)的橋梁。下面是對(duì) Vue 響應(yīng)式(雙向數(shù)據(jù)綁定)的理解,如果錯(cuò)誤盡請(qǐng)指出,一起交流,共同進(jìn)步。

Vue響應(yīng)式原理核心是 數(shù)據(jù)劫持,采用 ES5 的 object.defineproperty 的 getter 和 setter 方法。從一個(gè)例子出發(fā):

首先,在Vue初始化階段,通過(guò) observer 對(duì) data 中的屬性進(jìn)行遞歸的劫持,包括 name、job_ undergo、a、b等

在 get階段也就是初始化視圖時(shí),為每一個(gè)劫持的屬性分配一個(gè) 依賴收集器,主要收集當(dāng)前屬性的觀察者對(duì)象,例子中 name 屬性在模板中有兩處被使用,那么 name 屬性的依賴收集器中就存放兩個(gè)觀察者對(duì)象

當(dāng)點(diǎn)擊按鈕時(shí),將 name 修改為 lisi 時(shí),會(huì)觸發(fā) observer 的 setter 函數(shù),將 value 更新為 lisi 最新值,然后通知依賴收集器數(shù)據(jù)發(fā)生了更新。

依賴收集就是發(fā)布訂閱模式,依賴收集器會(huì)通知所有的觀察者對(duì)象,當(dāng)前name 屬性有兩個(gè)觀察者對(duì)象。

觀察者對(duì)象調(diào)用對(duì)應(yīng)的回調(diào)函數(shù)進(jìn)行相關(guān)的處理和DOM更新

以上是純響應(yīng)式原理的分析和總結(jié),下面配一張流程圖:

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

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

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

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

與其空談原理,不如讓我們來(lái)手寫一個(gè)簡(jiǎn)易版吧。

響應(yīng)式

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

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

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

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

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

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

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

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

圖片

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

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

這個(gè) Map 是在對(duì)象存在的時(shí)候它就存在,對(duì)象銷毀的時(shí)候它也要跟著銷毀。(因?yàn)閷?duì)象都沒(méi)了自然也不需要維護(hù)每個(gè) key 關(guān)聯(lián)的 effect 了)

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

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

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

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

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)就是圖中的那個(gè):

圖片

圖片

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

effect(() = {

console.log(obj.a);

});

也就是這樣:

const depsMap = reactiveMap.get(obj);

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

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

這樣維護(hù) deps 功能上沒(méi)啥問(wèn)題,但是難道要讓用戶手動(dòng)添加 deps 么?

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

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

那怎么自動(dòng)收集依賴呢?

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

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

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

當(dāng)你修改 obj.a 的時(shí)候,要通知所有的 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)式完成了,我們測(cè)試一下:

圖片

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

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

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

依賴也正確收集到了:

圖片

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

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

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

這樣一段代碼:

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,這時(shí)候會(huì)走到第一個(gè)分支,又依賴了 obj.b。

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

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

圖片

第一次打印 2 是對(duì)的,也就是走到了第一個(gè)分支,打印 obj.b

第二次打印 nothing 也是對(duì)的,這時(shí)候走到第二個(gè)分支。

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

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

圖片

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

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

記錄下就好了。

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

let activeEffect

function effect(fn) {

activeEffect = fn

fn()

}

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

let activeEffect

function effect(fn) {

const effectFn = () = {

activeEffect = effectFn

fn()

}

effectFn.deps = []

effectFn()

}

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

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

圖片

這樣下次再執(zhí)行這個(gè) effect 函數(shù)的時(shí)候,就可以把這個(gè) 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ù)組置空。

我們?cè)賮?lái)測(cè)試下:

圖片

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

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

圖片

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

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

圖片

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

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

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

圖片

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

再測(cè)試一次:

圖片

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

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

圖片

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

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

也不是,還有一個(gè)問(wèn)題:

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

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

我們嵌套下試試:

effect(() = {

console.log('effect1');

effect(() = {

console.log('effect2');

obj.b;

});

obj.a;

});

obj.a = 3;

按理說(shuō)會(huì)打印一次 effect1、一次 effect2,這是最開(kāi)始的那次執(zhí)行。

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

也就是會(huì)打印 effect1、effect2、effect1、effect2。

我們測(cè)試下:

圖片

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

為什么呢?

看下這段代碼:

圖片

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

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

怎么辦呢?

嵌套的話加一個(gè)棧來(lái)記錄 effect 不就行了?

也就是這樣:

圖片

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

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

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

我們?cè)贉y(cè)試一下:

圖片

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

至此,我們的響應(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ù)變化的時(shí)候做一系列聯(lián)動(dòng)的處理。

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

圖片

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

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

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

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

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

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

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

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

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

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

圖片

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

當(dāng)一個(gè)vue實(shí)例加載時(shí),會(huì)進(jìn)行初始化,將他的配置項(xiàng)options和mixins的內(nèi)容合并,以options為主,而在初始化data時(shí),會(huì)對(duì)data對(duì)象進(jìn)行數(shù)據(jù)劫持,并做代理,通過(guò)Object。

definproperty劫持?jǐn)?shù)據(jù)后vue會(huì)查找當(dāng)前屬性有無(wú)依賴項(xiàng)既被watch,或者依賴當(dāng)前屬性的值,如果有,就會(huì)注冊(cè)依賴既deps,而注冊(cè)deps時(shí)會(huì)在wather內(nèi)添加新的更新目標(biāo)。

當(dāng)數(shù)據(jù)發(fā)生變更時(shí),會(huì)觸發(fā)deps的更新方法,調(diào)用所有的watcher,watcher又會(huì)觸發(fā)對(duì)應(yīng)deps的更新,直到所有依賴項(xiàng)更新完畢。

擴(kuò)展資料:

Vue 是一個(gè) MVVM框架,核心是雙向數(shù)據(jù)綁定,VM(視圖模型)是作為V(視圖)和M(模型)的橋梁。對(duì)Vue響應(yīng)式(雙向數(shù)據(jù)綁定)的理解,如果錯(cuò)誤盡請(qǐng)指出,一起交流,共同進(jìn)步。Vue響應(yīng)式原理核心是 數(shù)據(jù)劫持,采用 ES5 的 object.defineproperty 的 getter 和 setter 方法。

Vue.js 最顯著的一個(gè)功能是響應(yīng)系統(tǒng) —— 模型只是普通對(duì)象,修改它則更新視圖。這讓狀態(tài)管理非常簡(jiǎn)單且直觀,不過(guò)理解它的原理也很重要,可以避免一些常見(jiàn)問(wèn)題。下面我們開(kāi)始深挖 Vue.js 響應(yīng)系統(tǒng)的底層細(xì)節(jié)。

參考資料來(lái)源:百度百科-Vue·js前端開(kāi)發(fā)技術(shù)

關(guān)于vue3響應(yīng)式原理代理與反射和vue3 響應(yīng)式原理的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。

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

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

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

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

易語(yǔ)言反編譯工具(易語(yǔ)言反編譯器)

易語(yǔ)言反編譯工具(易語(yǔ)言反編譯器)

本篇文章給大家談?wù)勔渍Z(yǔ)言反編譯工具,以及易語(yǔ)言反編譯器對(duì)應(yīng)的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、易語(yǔ)言怎么將一個(gè)文件寫入exe文件(文件是易語(yǔ)言編譯的)里且寫完后exe文件可以繼續(xù)運(yùn)行 2、怎樣把DLL反編譯成易語(yǔ)言源碼 3、.net,java都能被反編譯...

c反應(yīng)蛋白高說(shuō)明什么(c反應(yīng)蛋白高說(shuō)明什么新冠感染后)

c反應(yīng)蛋白高說(shuō)明什么(c反應(yīng)蛋白高說(shuō)明什么新冠感染后)

本篇文章給大家談?wù)刢反應(yīng)蛋白高說(shuō)明什么,以及c反應(yīng)蛋白高說(shuō)明什么新冠感染后對(duì)應(yīng)的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、c反應(yīng)蛋白高說(shuō)明什么 2、c反應(yīng)蛋白偏高說(shuō)明什么 3、c-反應(yīng)蛋白高是怎么回事 4、超敏c反應(yīng)蛋白偏高說(shuō)明什么 c反應(yīng)蛋白高說(shuō)明什么 C...

源碼商城交易平臺(tái)源碼支付寶(源碼交易網(wǎng))

源碼商城交易平臺(tái)源碼支付寶(源碼交易網(wǎng))

本篇文章給大家談?wù)勗创a商城交易平臺(tái)源碼支付寶,以及源碼交易網(wǎng)對(duì)應(yīng)的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、找一個(gè)網(wǎng)上商城源碼 2、商城怎么鏈接上支付寶支付! 3、支付寶的訂單系統(tǒng)怎么弄啊PHP源碼 4、支付寶支付頁(yè)面iapp源碼求誰(shuí)有 5、支付寶源代碼?...

中臺(tái)架構(gòu)與實(shí)現(xiàn)(中臺(tái)架構(gòu)與實(shí)現(xiàn)基于DDD和微服務(wù))

中臺(tái)架構(gòu)與實(shí)現(xiàn)(中臺(tái)架構(gòu)與實(shí)現(xiàn)基于DDD和微服務(wù))

今天給各位分享中臺(tái)架構(gòu)與實(shí)現(xiàn)的知識(shí),其中也會(huì)對(duì)中臺(tái)架構(gòu)與實(shí)現(xiàn)基于DDD和微服務(wù)進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問(wèn)題,別忘了關(guān)注本站,現(xiàn)在開(kāi)始吧!本文目錄一覽: 1、中臺(tái)是什么意思 2、數(shù)據(jù)中臺(tái)有什么好處? 3、業(yè)務(wù)中臺(tái)和數(shù)據(jù)中臺(tái)有什么關(guān)系? 4、百勝軟件E3全渠道中臺(tái)采用的什么底層架...

區(qū)塊鏈開(kāi)源網(wǎng)站(區(qū)塊鏈開(kāi)發(fā)平臺(tái))

區(qū)塊鏈開(kāi)源網(wǎng)站(區(qū)塊鏈開(kāi)發(fā)平臺(tái))

本篇文章給大家談?wù)剠^(qū)塊鏈開(kāi)源網(wǎng)站,以及區(qū)塊鏈開(kāi)發(fā)平臺(tái)對(duì)應(yīng)的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、區(qū)塊鏈應(yīng)用開(kāi)發(fā)找哪家好? 2、區(qū)塊鏈網(wǎng)站怎么搭建 3、國(guó)際首條車聯(lián)網(wǎng)區(qū)塊鏈IOV Blockchain于中國(guó)黃埔正式面向全球開(kāi)源 區(qū)塊鏈應(yīng)用開(kāi)發(fā)找哪家好? 區(qū)塊鏈...

快捷指令弄了圖標(biāo)為什么會(huì)有兩個(gè)軟件(為什么用快捷指令改了圖標(biāo)卻還有另另外的軟件出現(xiàn))

快捷指令弄了圖標(biāo)為什么會(huì)有兩個(gè)軟件(為什么用快捷指令改了圖標(biāo)卻還有另另外的軟件出現(xiàn))

今天給各位分享快捷指令弄了圖標(biāo)為什么會(huì)有兩個(gè)軟件的知識(shí),其中也會(huì)對(duì)為什么用快捷指令改了圖標(biāo)卻還有另另外的軟件出現(xiàn)進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問(wèn)題,別忘了關(guān)注本站,現(xiàn)在開(kāi)始吧!本文目錄一覽: 1、為什么我每次點(diǎn)開(kāi)一個(gè)程序,桌面就會(huì)出現(xiàn)兩個(gè)快捷方式 2、手機(jī)桌面出現(xiàn)兩個(gè)同樣軟件怎么回事?...

盘山县| 梅州市| 富阳市| 辽宁省| 拉萨市| 即墨市| 呼玛县| 抚州市| 巴马| 武山县| 张家界市| 西平县| 淳安县| 广昌县| 应用必备| 临泉县| 铜川市| 泽库县| 焦作市| 桑植县| 长岛县| 多伦县| 永寿县| 临邑县| 大悟县| 新源县| 绿春县| 江油市| 普宁市| 华亭县| 常山县| 肥西县| 和林格尔县| 喀喇沁旗| 额济纳旗| 乳源| 濉溪县| 清徐县| 克什克腾旗| 泰兴市| 巴塘县|