1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| type IFunc = (...res: any[]) => any; let reactiveFn: IFunc | null = null; class Depend { reactiveFns: Set<IFunc>; constructor() { this.reactiveFns = new Set<IFunc>(); } addDepend() { reactiveFn && this.reactiveFns.add(reactiveFn); } notify() { this.reactiveFns.forEach((fn) => { fn(); }); } }
const targetMap = new WeakMap<Record<string, any>, Map<string, Depend>>(); function getDepend(target: Record<string, any>, key: string) { if (!targetMap.has(target)) { const map = new Map<string, Depend>(); targetMap.set(target, map); } const map = targetMap.get(target); if (!map?.has(key)) { const depend = new Depend(); map?.set(key, depend); } return map?.get(key); } function watchFn(fn: IFunc) { reactiveFn = fn; fn(); reactiveFn = null; } function reactive(obj: Record<string, any>) { return new Proxy(obj, { get(target, key: string, receiver) { const depend = getDepend(target, key); depend?.addDepend(); return Reflect.get(target, key, receiver); }, set(target, key: string, value, receiver) { Reflect.set(target, key, value, receiver); const depend = getDepend(target, key); console.log("修改属性------------");
depend?.notify(); return true; }, }); } const info = reactive({ name: "cy", age: 24, }); watchFn(() => { console.log(info.name, "info"); });
watchFn(() => { console.log(info.age, "info"); }); const info2 = reactive({ name: "tyz", age: 23, });
watchFn(() => { console.log(info2.name, "info2"); }); info.name = "tyz";
info2.name = "cy";
|