Reactive的响应式

2023/6/21 proxy

Reactive的内部怎么实现响应式呢?

# Proxy

reactive的作用其实就是在原对象外层套了一层 Proxy 对象,所以我们想要分析 reactive 的响应式,那就要先理解一下Proxy在中间做了什么

我们可以自己先定义一个 Proxy 对象,用它来封装一下我们的原对象

先不写 Handler 的逻辑,看一下此时能实现什么功能

const person = {
  name: "smeb",
  age: 18,
};

const p1 = new Proxy(person, {});

1

发现这时候其实已经实现了数据代理的功能,我们通过修改 p1 的 name 和 age,是可以修改原数据 person 的值的

那到现在不就结束了么,其实并没有,因为我们要讨论的是响应式,现在只是实现了数据代理的功能,之所以会这样想是因为很多人会觉得数据代理就是响应式,而我们通过这样一个例子说明了一个不设置任何 Handler 的 Proxy 就可以实现数据代理

# 响应式

响应式不是数据代理,而是数据劫持,所以要实现响应式的效果,其实就是要完成数据劫持,而要想实现它,就要依靠 Handler 了

const p = new Proxy(person, {
  //有人读取p的某个属性时调用
  get(target, propName) {
    console.log(`读取了person身上的${propName}属性`);
    return target[propName];
  },
  //有人修改p的某个属性、或给p追加某个属性时调用
  set(target, propName, value) {
    console.log(`修改了person身上的${propName}属性,需要更新界面了`);
    target[propName] = value;
  },
  //有人删除p的某个属性时调用
  deleteProperty(target, propName) {
    console.log(`删除了person身上的${propName}属性,需要更新界面了`);
    // return Reflect.deleteProperty(target, propName);
    delete target[propName];
  },
});

2

通过设置了 Proxy 的 Handler,类似于配置对象,get —— 读取,增加, set —— 修改,deleteProperty —— 删除

这时我们就实现了数据劫持的效果了,也就可以进一步实现了响应式了

但现在还存在一个问题,仔细看代码可以看到,我们在Handler中实现对原数据的增删改查时,其实是在直接操作原数据,这并没有什么不对的地方,只是,我们在vue或者其他封装好的框架中,尽量就不要直接修改原数据,因为如果我们操作时发生了 error,会直接报错,从而影响我们后面代码的运行,这在实际开发中是很严重的问题,我们可以通过对操作进行try...catch,来捕获错误的来源,但实际操作起来是很麻烦的

# Reflect

ECMA6之后,慢慢的尝试将Object上的一些Api移到了Reflect(反射对象)上,Reflect 相比较于Object的优点,就是它有一个返回值,如果这条语句成功执行了,就返回 true,反之返回 false

有了这个返回值,对于后面的代码,vue 就可以很轻松的进行逻辑处理了

const p = new Proxy(person, {
  //有人读取p的某个属性时调用
  get(target, propName) {
    console.log(`读取了person身上的${propName}属性`);
    return Reflect.get(target, propName);
  },
  //有人修改p的某个属性、或给p追加某个属性时调用
  set(target, propName, value) {
    console.log(`修改了person身上的${propName}属性,需要更新界面了`);
    return Reflect.set(target, propName, value);
  },
  //有人删除p的某个属性时调用
  deleteProperty(target, propName) {
    console.log(`删除了person身上的${propName}属性,需要更新界面了`);
    return Reflect.deleteProperty(target, propName);
  },
});

3

综上所述,vue3中的reactive响应式原理底层大概就是这个逻辑了~

How to love
Lil Wayne