响应式系统Vue2实现-依赖收集系统
class Dep {
constructor() {
this.subscribers = new Set();
}
depend() {
if (actineEffect) {
this.subscribers.add(actineEffect)
}
}
notify() {
this.subscribers.forEach(effect => {
effect();
})
}
}
let actineEffect = null;
function watchEffect(effect) {
actineEffect = effect;
effect();
actineEffect = null;
}
// Map({key:value}):key是一个字符串;
// WeakMap({key(对象):vlaue}):key是一个对象,弱引用
const targetMap = new WeakMap();
function getDep(target, key) {
// 1、根据对象(taeget)取出对应的Map对象
let depsMap = targetMap.get(target);
if (!depsMap) {
depsMap = new Map();
targetMap.set(target, depsMap)
}
// 2、取出具体的dep对象;
let dep = depsMap.get(key);
if (!dep) {
dep = new Dep();
depsMap.set(key, dep);
}
return dep
}
// vue2对raw进行数据劫持
function reactive(raw) {
Object.keys(raw).forEach(key => {
const dep = getDep(raw, key);
let value = raw[key];
Object.defineProperty(raw, key, {
// 获取数据钓鱼用get
get() {
dep.depend();
return value;
},
// 设置数据用set
set(newValue) {
if (value !== newValue) {
value = newValue;
dep.notify();
}
}
})
})
return raw
}
/* 测试代码 */
const info = reactive({
counter: 100,
name: 'pei'
});
const foo = reactive({
height: 1.63
})
// watchEffect1
watchEffect(function() {
console.log("打印1", info.counter * 2)
})
// watchEffect2
watchEffect(function() {
console.log("打印2", info.counter * info.counter)
})
// watchEffect3
watchEffect(function() {
console.log("打印3", info.counter + 10, info.name)
})
// watchEffect4
watchEffect(function() {
console.log("打印4", foo.height)
})
info.counter++;
版权声明:本文为peijiajing原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。