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)})