vue2与vue3的响应式原理简单示例

87 阅读1分钟

vue2中写在data中的数据在执行时候,vue会把这些数据用Object.defineProperty进行代理,然后在其它地方读取到的这个数据其实是代理后的数据

// 原始数据
let obj = { name: "张三", sex: 1 };

// vue2代理数据
let p = {};
Object.defineProperty(p, "name", {
  get() {
    console.log(`读取了name`);
    return obj.name;
  },
  set(value) {
    console.log(`修改了name`);
    obj.sex = value;
  },
});
Object.defineProperty(p, "sex", {
  get() {
    console.log(`读取了sex`);
    return obj.sex;
  },
  set(value) {
    console.log(`修改了sex`);
    obj.sex = value;
  },
});

// vue3代理数据
let pp = new Proxy(obj, {
  get(target, key) {
    console.log(`读取了${key}`);
    return target[key];
  },
  // 修改和增加属性的时候都会触发
  set(target, key, value) {
    console.log(`修改了${key}`);
    target[key] = value;
  },
  deleteProperty(target, key) {
      console.log(`删除了${key}`);
      return delete target[key];
  },
});

如果说Object.defineProperty是“属性级别的代理”(因为它针对单个属性设置getter和setter进行拦截),那么Proxy可以形容为“对象级别的代理”或者“全方位代理”。Proxy提供了一种更全面的方式来拦截并自定义对象的基本操作,比如获取属性值(get)、设置属性值(set)、枚举(enumerate)、删除(delete)等,几乎覆盖了对象的所有可代理行为。因此,用“全面托管”或“高级中介”来形容Proxy的操作也非常贴切,因为它可以在对象访问的任何环节介入并控制流程。