what
- 当变量变化的时候,涉及到这个变量的操作重新执行
- 更多是针对对象类型进行监听(原始数据类型是不变的,任何的修改实质是创建了新值)
how
- 响应式对象创建
Proxy
- 响应式对象与依赖之间的映射关系
weakMap-map-set
- 依赖函数收集
创建响应式对象
vue3
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
const depend = getDepend(target, key);
depend.addDepend();
return Reflect.get(target, key);
},
set(target, key, value) {
const depend = getDepend(target, key);
depend.notify();
Reflect.set(target, key, value);
},
});
}
vue2方式
function reactive2(obj){
Object.keys(obj).forEach(key=>{
let value = obj[key]
Object.defineProperty(obj,key,{
get(){
const depend = getDepend(obj,key)
depend.depend()
return value
},
set(newValue){
const depend = getDepend(obj,key)
depend.notify()
value = newValue
}
})
})
return obj
}
对象-依赖关系
let targetMap = new WeakMap();
class Depend {
constructor() {
this.reactiveFns = new Set();
}
addDepend() {
if (activeReactiveFn) {
this.reactiveFns.add(activeReactiveFn);
}
}
notify() {
this.reactiveFns.forEach((fn) => {
if(fn){
fn()
}
});
}
}
function getDepend(target, key) {
let map = targetMap.get(target);
if (!map) {
map = new Map();
targetMap.set(target, map);
}
let depend = map.get(key);
if (!depend) {
depend = new Depend();
map.set(key, depend);
}
return depend;
}
依赖函数收集
let activeReactiveFn = null;
function watchFn(fn) {
activeReactiveFn = fn;
fn();
activeReactiveFn = null;
}
使用
const obj = {
name: "张三",
age: 18,
};
const objRef = reactive(obj);
watchFn(()=>{
console.log(objRef.name)
})
watchFn(()=>{
console.log(objRef.age)
})