您好,登錄后才能下訂單哦!
這篇文章主要介紹“vue3響應式實現readonly的方法是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“vue3響應式實現readonly的方法是什么”文章能幫助大家解決問題。
it("happy path", () => { console.warn = vi.fn(); const original = { foo: 1, }; const observed = readonly({ foo: 1, }); expect(original).not.toBe(observed); expect(observed.foo).toBe(1); // set不起作用 observed.foo = 2; expect(observed.foo).toBe(1); // 當被set的時候,發出一個警告 expect(console.warn).toBeCalled(); });
其實與我們之前實現 reactive
十分的類似,區別只不過是set
的時候不要觸發trigger,而是警告。當然既然是不會被改變的,track
也是不必要的。
export function readonly(raw) { return new Proxy(raw, { get(target, key) { const res = Reflect.get(target, key); return res; }, set(target, key, newValue, receiver) { console.warn( `property: ${String(key)} can't be set, beacase ${target} is readonly.` ); return true; }, }); } export function reactive(raw) { return new Proxy(raw, { get(target, key) { const res = Reflect.get(target, key); // 依賴收集 track(target, key); return res; }, set(target, key, value) { const res = Reflect.set(target, key, value); // 觸發依賴 trigger(target, key); return res; }, }); }
可以看到,readonly
和 reactive
實現其實很類似,那我們可以重構一下,增強后續的拓展性。
至于我說的類似,指的是 new Proxy(target, handlers)
中的handlers(處理器對象)中的一些traps(捕獲器)。即get
, set
這些方法。
我們可以通過工廠函數來創建那些traps函數,來簡化我們的代碼,提高可維護性。
另外,我們假定traps可以有工廠可以生產了,即handlers這部分相當于被定下來了,new Proxy
這部分也理應可以通過工廠函數創造出來。
我們先抽出一個公共的文件 baseHandler.ts
// baseHanlder.ts import { track, trigger } from "./effect"; // get的工廠函數 function createGetter(isReadonly = false) { return function get(target, key) { const res = Reflect.get(target, key); if (!isReadonly) { track(target, key); } return res; }; } function createSetter() { return function set(target, key, newValue, receiver) { const res = Reflect.set(target, key, newValue, receiver); trigger(target, key, type, newValue); return res; }; } export const mutableHandler = { get: createGetter(), set: createSetter(), }; export const readonlyHandler = { get: createGetter(), set(target, key, newValue, receiver) { console.warn( `property: ${String(key)} can't be set, beacase ${target} is readonly.` ); return true; };
然后是我們的reactive.ts
// reactive.ts import { mutableHandler, readonlyHandler, } from "./baseHandlers"; // proxy的工廠函數 function createReactiveObject( target, baseHandlers: ProxyHandler<any> ) { return new Proxy(target, baseHandlers); } export function reactive(target) { return createReactiveObject(target, mutableHandler); } export function readonly(target) { return createReactiveObject(target, readonlyHandler); }
關于“vue3響應式實現readonly的方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。