跳至主要內容

Vue响应式实现

yyshino大约 2 分钟FrontEndJS

原理

ProxyObject.defineProperty

  1. Proxy
    1. Proxy 将代理一个对象(被代理对象),得到一个新的对象(代理对象),同时拥有被代理对象中所有的属性。
    2. 当想要修改对象的指定属性时,我们应该使用代理对象进行修改
    3. 代理对象 的任何一个属性都可以触发 handlergettersetter
  2. Object.defineProperty
    1. Object.defineProperty 为指定对象的指定属性设置属性描述符
    2. 当想要修改对象的指定属性时,可以使用原对象进行修改
    3. 通过属性描述符,只有 被监听 的指定属性,才可以触发 gettersetter

所以当 vue3 通过 Proxy 实现响应性核心 API 之后,vue 将 不会 再存在新增属性时失去响应性的问题。

Reflect

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect

Reflect+Proxy

当我们期望监听代理对象的 getter 和 setter 时,不应该使用 target[key] ,因为它在某些时刻(比如 fullName)下是不可靠的。而 应该使用 Reflect ,借助它的 get 和 set 方法,使用receiver (proxy 实例) 作为 this,已达到期望的结果(触发三次 getter)

最后如果我们想要“安全”的使用Proxy,还需要配合Reflect一起才可以,因为一旦我们在被代理对象的内部,通过 this 触发 getter 和 setter 时,也需要被监听到。