what
- 当变量变化的时候,涉及到这个变量的操作重新执行
- 更多是针对对象类型进行监听(原始数据类型是不变的,任何的修改实质是创建了新值)
how
- 响应式对象创建
Proxy
- 响应式对象与依赖之间的映射关系
weakMap-map-set
- 依赖函数收集
创建响应式对象
vue3
js
//响应式对象创建
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方式
js
//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
}
对象-依赖关系
js
let targetMap = new WeakMap(); // 响应式对象与依赖关系的映射 1.对象与属性的映射 2.属性与依赖函数的映射
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) {
//1.根据target获取map
let map = targetMap.get(target);
if (!map) {
map = new Map();
targetMap.set(target, map);
}
//2.根据key获取depend
let depend = map.get(key);
if (!depend) {
depend = new Depend();
map.set(key, depend);
}
return depend;
}
依赖函数收集
js
let activeReactiveFn = null; // 当前激活的响应式函数
//响应式函数收集---被watchFn收集的函数会成为响应式的依赖,当数据变化这些函数会被调用
function watchFn(fn) {
activeReactiveFn = fn;
fn();
activeReactiveFn = null;
}
使用
js
const obj = {
name: "张三",
age: 18,
};
//1.创建响应式对象
const objRef = reactive(obj);
//2.收集依赖函数
watchFn(()=>{
console.log(objRef.name)
})
watchFn(()=>{
console.log(objRef.age)
})