根据官网代码介绍实现 类似 watchEffect功能
<script lang="ts" setup>
let count = {
a1: 1,
a2: 2
};
let total = 0;
let activeEffect: any = null;
const WeakMap = new Map<string, any>();
const reactive = (object: object) => {
return new Proxy(object, {
get(target: object, key: string, receiver: any): any {
track(target, key);
return target[key]
},
set(target: object, key: string, value: any, receiver: any): boolean {
target[key] = value;
trigger(target, key);
return true
}
})
};
const getSubscribersForProperty = (target: object, key: string) => {
if (!WeakMap.get(key)) {
const row = new Set();
WeakMap.set(key, row)
}
return WeakMap.get(key)
};
const track = (target: any, key: string) => {
if (activeEffect) {
// 副作用订阅将被存储在一个全局的 WeakMap<target, Map<key, Set<effect>>> 数据结构中
const effects = getSubscribersForProperty(target, key);
if (effects) {
effects.add(activeEffect)
}
}
};
const trigger = (target: any, key: string) => {
const effects = getSubscribersForProperty(target, key);
effects?.forEach((effect: any) => {
effect()
})
};
const customWatch = (update: Function) => {
const effect = () => {
activeEffect = effect;
update();
activeEffect = null;
};
effect();
};
// demo
const reactiveCount = reactive(count);
customWatch(() => {
total = reactiveCount.a1 + reactiveCount.a2;
console.log(total);
});
setTimeout(() => {
// 任意依赖被改动时重新运行 customWatch 打印为 6
reactiveCount.a1 = 4;
}, 1000);
setTimeout(() => {
// 任意依赖被改动时重新运行 customWatch 打印为 8
reactiveCount.a2 = 4;
}, 2000);
</script>
网友评论