Vue3 响应式源码实现

2022 年 4 月 11 日 星期一(已编辑)
/ ,
10
这篇文章上次修改于 2024 年 7 月 20 日 星期六,可能部分内容已经不适用,如有疑问可询问作者。

Vue3 响应式源码实现

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      const depend = getDepend(target, key);
      depend.addDepend();
      return Reflect.get(target, key, receiver);
    },
    set(target, key, newValue, receiver) {
      console.log(`对象的${key}值改变为了${newValue}`);
      Reflect.set(target, key, newValue, receiver);
      const depend = getDepend(target, key);
      depend.notify();
    },
  });
}
let curDepsFunc = null;
class Deps {
  constructor() {
    this.dep = new Set();
  }
  addDepend() {
    if (curDepsFunc) {
      this.dep.add(curDepsFunc);
    }
  }
  notify() {
    for (const fn of this.dep) {
      fn();
    }
  }
}

const dependWeakMap = new WeakMap();
function getDepend(target, key) {
  let depsMap = dependWeakMap.get(target);
  if (!depsMap) {
    depsMap = new Map();
    dependWeakMap.set(target, depsMap);
  }
  let deps = depsMap.get(key);
  if (!deps) {
    deps = new Deps();
    depsMap.set(key, deps);
  }
  return deps;
}
function watchEffect(fn) {
  curDepsFunc = fn;

  fn();
}
const proxyObj = reactive({
  name: 'Kobe',
  age: 18,
});
watchEffect(function () {
  console.log(proxyObj.name);
  console.log(proxyObj.age);
});
// watchEffect(function () {
//   console.log(proxyObj.age);
// });
proxyObj.name = 'wangweiping';
proxyObj.name = 'xieting';
proxyObj.age = 2012;

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...