Vue3中Proxy、effectWatch的简单实现

88 阅读1分钟

// 依赖
let currentEffect;

class Dep {
  //1.收集以依赖
  constructor(val) {
    this.effects = new Set()
    this._val = val
  }
  get value() {
    this.depend()
    return this._val
  }
  set value(newValue) {
    this._val = newValue
    this.notice()
  }
  depend() {
    //存储依赖
    if (currentEffect) {
      this.effects.add(currentEffect)
    }
  }
  //2.触发依赖
  notice() {
    this.effects.forEach(effect => {
      effect()
    });
  }
}
function effectWatch(effect) {
  //收集依赖
  currentEffect = effect
  effect()
  currentEffect = null
}



const dep = new Dep(10)
let b;
effectWatch(() => {
  b = dep.value + 10
  console.log(b)
})
//值发生变更
dep.value = 20;

const targetMap = new Map()

function getDep(target, key) {
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    depsMap = new Map();
    targetMap.set(target, depsMap)
  }

  let dep = depsMap.get(key);
  if (!dep) {
    dep = new Dep();
    depsMap.set(key, dep)
  }
  return dep
}

function reactive(raw) {
  return new Proxy(raw, {
    get(target, key) {
      //key--dep
      //dep 我们存储在哪里
      console.log('触发reactive中Proxy的get方法', target, key)
      const dep = getDep(target, key);
      dep.depend();
      return Reflect.get(target, key)
    },
    set(target, key, value) {
      //触发依赖
      //要获取到dep
      console.log('触发reactive中Proxy的set方法', target, key, value)
      const dep = getDep(target, key);
      const result = Reflect.set(target, key, value)
      dep.notice();
      return result;
    },
  })
}
// const user = reactive({
//   age: 19,
// });
// console.log(user)
// let double;
// effectWatch(() => {
//   console.log("---reactive---")
//   double = user.age;
//   console.log(double);
// })
// user.age = 20;