淺析Vue為什么需要同時(shí)使用Ref和Reactive
在使用 Options API 工作時(shí)聲明響應(yīng)性數(shù)據(jù)是直截了當(dāng)?shù)摹?code>data 選項(xiàng)內(nèi)的所有內(nèi)容都會(huì)自動(dòng)變?yōu)轫憫?yīng)性,并在模板中可用。唯一需要注意的是,要將data設(shè)為一個(gè)函數(shù),以防止在所有組件實(shí)例之間共享狀態(tài)。
讓我們討論一下Vue 3中發(fā)生了什么變化,以及為什么我們需要兩個(gè)不同的助手。
Vue 2中的響應(yīng)性
data 組件選項(xiàng)內(nèi)的每個(gè)屬性都將通過(guò) Object.defineProperty 轉(zhuǎn)換為getter/setter。這些getter/setter對(duì)我們來(lái)說(shuō)是看不見(jiàn)的,但在底層,它們使Vue在訪問(wèn)或修改屬性時(shí)能夠執(zhí)行依賴跟蹤。
每個(gè)組件都有一個(gè)關(guān)聯(lián)的觀察者,用于跟蹤在組件的渲染周期中使用的屬性。如果依賴項(xiàng)更新,觀察者會(huì)通知組件,然后觸發(fā)重新渲染。
Vue 3中的響應(yīng)性
在 Vue 3 中,一切都發(fā)生了變化。核心部分從零開(kāi)始重寫(xiě),現(xiàn)在由Javascript Proxies提供響應(yīng)性。Proxies是一種現(xiàn)代且優(yōu)雅的方式來(lái)觀察一個(gè)對(duì)象并在其屬性被訪問(wèn)或更新時(shí)得到通知。
可以通過(guò)以下簡(jiǎn)單的例子來(lái)理解代理是如何工作的:
const userInfo = {
firstName: "fotis",
age: 35,
};
const handler = {
get(target, property) {
if (property === "firstName") {
const name = target[property]
return name.charAt(0).toUpperCase() + name.slice(1);
}
if (property === "age") {
return '--'
}
return target[property]
},
};
const proxy = new Proxy(userInfo, handler);
console.log(proxy.firstName) // "Fotis"
console.log(proxy.age) // "--"處理器內(nèi)部的get方法被稱(chēng)為陷阱,每次訪問(wèn)對(duì)象的屬性時(shí)都會(huì)被調(diào)用。以類(lèi)似的方式,可以定義一個(gè)設(shè)定的陷阱:
const userInfo = {
firstName: "Fotis",
age: 35,
};
const handler = {
set(target, prop, value) {
if (prop === "age") {
if (!Number.isInteger(value)) {
throw new TypeError("The age is not an integer");
}
if (value > 200) {
throw new RangeError("The age seems invalid");
}
}
target[prop] = value;
return true;
},
};
const proxy = new Proxy(userInfo, handler);
proxy.age = 12 // OK
proxy.age = 300 // Error: The age seems invalid這正是 Vue 3 響應(yīng)性背后的理念。當(dāng)使用 reactive 助手聲明一個(gè)變量時(shí),會(huì)使用一個(gè) proxy. 來(lái)跟蹤任何變化。
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
track(target, key)
return target[key]
},
set(target, key, value) {
target[key] = value
trigger(target, key)
}
})
}當(dāng)然,響應(yīng)式助手的實(shí)際實(shí)現(xiàn)更為復(fù)雜,能處理邊緣情況,但其核心仍然使用proxy。
以上的片段解釋了為什么將響應(yīng)性變量解構(gòu)或重新分配給本地變量后,它就不再具有反應(yīng)性,因?yàn)樗辉儆|發(fā)源對(duì)象上的 get/set proxy 陷阱。
這看起來(lái)像是一個(gè)完美的解決方案,可以使所有事物都變成響應(yīng)式。但是有個(gè)問(wèn)題!根據(jù)定義,proxy只適用于復(fù)雜類(lèi)型。這些包括對(duì)象、數(shù)組、映射和集合。要使一個(gè)原始類(lèi)型變得反應(yīng)靈敏,我們?nèi)匀恍枰褂么?,但首先我們必須將其包裝在一個(gè)對(duì)象中。
function ref(value) {
const refObject = {
get value() {
track(refObject, 'value')
return value
},
set value(newValue) {
value = newValue
trigger(refObject, 'value')
}
}
return refObject
}這解釋了為什么必須在 script setup 中使用煩人的 .value 。而且,再次重構(gòu)或重新分配給本地變量也是行不通的。
總結(jié)
那么,為什么需要 Ref 和 Reactive的答案是:Proxy。對(duì)于復(fù)雜類(lèi)型,它們可以直接使用,但對(duì)于原始類(lèi)型,需要?jiǎng)?chuàng)建一個(gè)代理對(duì)象。
希望,理解Vue的內(nèi)部工作原理可以使你更有效,并且可以消除 ref 和 reactive 之間的任何混淆。
以上就是淺析Vue為什么需要同時(shí)使用Ref和Reactive的詳細(xì)內(nèi)容,更多關(guān)于Vue Ref Reactive的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
如何解決this.$refs.form.validate()不執(zhí)行的問(wèn)題
這篇文章主要介紹了如何解決this.$refs.form.validate()不執(zhí)行的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
vue寫(xiě)一個(gè)全局彈窗組件通過(guò)js調(diào)用的方法
彈窗效果是在Web開(kāi)發(fā)中經(jīng)常用到的一種交互效果,它可以在用戶點(diǎn)擊某個(gè)按鈕或者觸發(fā)某個(gè)事件時(shí)顯示一個(gè)懸浮框,提供用戶與頁(yè)面進(jìn)行交互的機(jī)會(huì),這篇文章主要給大家介紹了關(guān)于vue寫(xiě)一個(gè)全局彈窗組件通過(guò)js調(diào)用的方法,需要的朋友可以參考下2024-06-06
vue實(shí)現(xiàn)三級(jí)導(dǎo)航展示和隱藏
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)三級(jí)導(dǎo)航展示和隱藏,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
Element的el-tree控件后臺(tái)數(shù)據(jù)結(jié)構(gòu)的生成以及方法的抽取
這篇文章主要介紹了Element的el-tree控件后臺(tái)數(shù)據(jù)結(jié)構(gòu)的生成以及方法的抽取,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
Vue項(xiàng)目之ES6裝飾器在項(xiàng)目實(shí)戰(zhàn)中的應(yīng)用
作為一個(gè)曾經(jīng)的Java?coder,當(dāng)?shù)谝淮慰吹絡(luò)s里面的裝飾器Decorator,就馬上想到了Java中的注解,當(dāng)然在實(shí)際原理和功能上面,Java的注解和js的裝飾器還是有很大差別的,這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目之ES6裝飾器在項(xiàng)目實(shí)戰(zhàn)中應(yīng)用的相關(guān)資料,需要的朋友可以參考下2022-06-06
vue-admin-template模板添加tagsview的實(shí)現(xiàn)
本文主要介紹了vue-admin-template模板添加tagsview的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
解決vue-element-admin中配置跨域出現(xiàn)的問(wèn)題
這篇文章主要介紹了解決vue-element-admin中配置跨域出現(xiàn)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07

