您好,欢迎访问一九零五行业门户网

vue3响应式实现readonly的方法是什么

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.tsimport { 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.tsimport { 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的方法是什么的详细内容。
其它类似信息

推荐信息