Vue2 响应式源码实现

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

Vue2 响应式源码实现

function reactive(obj) {
  Object.keys(obj).forEach((key) => {
    let value = obj[key];
    Object.defineProperty(obj, key, {
      get() {
        const depend = getDepend(obj, key);
        depend.addDepend();
        return value;
      },
      set(newVal) {
        value = newVal;
        const depend = getDepend(obj, key);
        depend.notify();
      },
    });
  });
  return obj;
}
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...