Proxy与响应式

137 阅读2分钟

为什么需要Proxy?

Vue3的核心特征之一就是响应式,而实现数据响应式依赖于底层的Proxy。因此,想要完成Vue的响应式功能,首先需要理解Proxy。

reactive为例,当想要创建一个响应式对象时,仅需要使用reactive对原始对象进行包裹。例如:

const user = reactive({
  age: 25
})

在Vue3的官方文档中,对reactive的描述是:返回对象的响应式副本。既然是响应式副本,就需要产生一个与原始对象含有相同内容的响应式对象,之后使用这个响应式对象替代原始对象,代替原始对象去做事情。这就体现了Proxy的价值——创建原始对象的代理

Proxy创建的代理对象与原始对象有何不同?

先来看看如何使用Proxy创建代理对象。

let proxy = new Proxy(target, handler)

Proxy可以接收两个参数,其中,target表示被代理的原始对象,handler表示代理配置,代理配置中的捕捉器允许我们拦截重新定义针对代理对象的操作。因此,如果在Proxy中,不进行任何代理配置,Proxy仅会成为原始对象的一个透明包装器(仅创建原始对象副本,但不产生任何其它功能)。因此,为了利用Proxy实现响应式对象,我们必须使用Proxy中的代理配置

在JavaScript规范中,存在一个描述JavaScript运行机制的“内部方法”。其中,读取属性的操作被称为[[Get]]设置属性的操作被称为[[Set]]。通常,我们无法直接使用这些“内部方法”,但Proxy给我们提供了捕捉器,使得对读取和设置操作的拦截成为可能。

const p = new Proxy(obj, {
  get(target, property, receiver) {/*拦截读取属性操作*/}
  set(target, property, value, receiver) {/*拦截设置属性操作*/}
})

其中,target为被代理的原始对象,property为原始对象的属性名,value为设置目标属性的值receiver是属性所在的this对象,即Proxy代理对象。

参考资料