reactive readonly嵌套對(duì)象轉(zhuǎn)換功能實(shí)現(xiàn)詳解
一、單元測(cè)試
reactive
// src/reactivity/tests/reactive.spec.ts
it('nested reactive', () => {
const original = {
nested: { foo: 1 },
array: [{ bar: 2 }]
};
const observed = reactive(original);
expect(isReactive(observed.nested)).toBe(true);
expect(isReactive(observed.array)).toBe(true);
expect(isReactive(observed.array[0])).toBe(true);
});
readonly
it('nested readonly', () => {
const original = { foo: 1, bar: { baz: 2 } };
const wrapped = readonly(original);
expect(isReadonly(wrapped)).toBe(true);
expect(isReadonly(wrapped.bar)).toBe(true);
});
二、代碼實(shí)現(xiàn)
為什么嵌套的深層對(duì)象沒(méi)有轉(zhuǎn)換成reactive、readonly呢?
因?yàn)?code>Proxy劫持的是對(duì)象本身,并不能劫持子對(duì)象的變化。
其實(shí)通過(guò)單測(cè)可以看出,我們只需要將reactive嵌套的里層對(duì)象也轉(zhuǎn)換成reactive,將readonly嵌套的里層對(duì)象也轉(zhuǎn)換成readonly。
那只需要在get中,返回res的時(shí)候,將res轉(zhuǎn)換成相應(yīng)的代理就可以了。
function createGetter(isReadonly = false) {
return function get(target, key) {
const res = Reflect.get(target, key);
if (key === ReactiveFlags.IS_REACTIVE) {
return !isReadonly;
} else if (key === ReactiveFlags.IS_READONLY) {
return isReadonly;
}
if (isObject(res)) {
return isReadonly ? readonly(res) : reactive(res);
}
if (!isReadonly) {
track(target, key);
}
return res;
};
}
跑一下完整的單測(cè)結(jié)果看下:

ps: 其實(shí)這里需要注意的一點(diǎn)就是,在get中處理嵌套轉(zhuǎn)換,我們只有在用到這個(gè)子對(duì)象的時(shí)候,才會(huì)將這個(gè)子對(duì)象 轉(zhuǎn)換成響應(yīng)時(shí)代理,避免了不必要的性能浪費(fèi)。對(duì)比vue2的遞歸遍歷defineProperty來(lái)說(shuō),也是一個(gè)優(yōu)化的地方。
以上就是reactive readonly嵌套對(duì)象轉(zhuǎn)換功能實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于reactive readonly嵌套對(duì)象轉(zhuǎn)換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用vue開(kāi)發(fā)移動(dòng)端管理后臺(tái)的注意事項(xiàng)
這篇文章主要介紹了使用vue開(kāi)發(fā)移動(dòng)端管理后臺(tái)的注意事項(xiàng),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03
在vue項(xiàng)目中集成graphql(vue-ApolloClient)
這篇文章主要介紹了在vue項(xiàng)目中集成graphql(vue-ApolloClient),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue使用Google Recaptcha驗(yàn)證的實(shí)現(xiàn)示例
我們最近的項(xiàng)目中需要使用谷歌機(jī)器人驗(yàn)證,所以就動(dòng)手實(shí)現(xiàn)一下,本文就來(lái)詳細(xì)的介紹一下vue Google Recaptcha驗(yàn)證,感興趣的可以了解一下2021-08-08
vue如何通過(guò)點(diǎn)擊事件彈出彈窗頁(yè)面詳解
彈窗是我們開(kāi)發(fā)中經(jīng)常遇到的一個(gè)功能,下面這篇文章主要給大家介紹了關(guān)于vue如何通過(guò)點(diǎn)擊事件彈出彈窗頁(yè)面的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
Vue router錯(cuò)誤跳轉(zhuǎn)到首頁(yè)("/")的問(wèn)題及解決
這篇文章主要介紹了Vue router錯(cuò)誤跳轉(zhuǎn)到首頁(yè)("/")的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10

