Vue 3.0中的响应式实现原理-1

354 阅读2分钟

这是我参与8月更文挑战的第28天,活动详情查看: 8月更文挑战

前言

Vue 2.x是利用Object.defineProperty()方法侦测对象的属性变化,但该方法有一些固有的缺陷:

  1. 性能较差
  2. 在对象上新增属性是无法被侦测的
  3. 改变数组的length属性时无法被侦测的

Vue 3.0 响应式系统的实现原理

Vue 3.0使用ES6的Proxy取代Object.defineProperty()方法,性能更优异,而且数组和对象一样,可以直接触发get()和set()方法。Proxy称为代理,是一种可以拦截并改变底层JavaScript引擎操作的包装器。

调用new Proxy(target, handler)可以为一个目标对象创建一个代理,代理可以拦截JavaScript引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响应特定操作的陷阱函数。在调用Proxy构造函数时,需要传入两个参数,target为目标对象;handler是一个包含陷阱函数的处理器对象中。

// 处理器对象
const baseHandler = {
  // 陷阱函数,读取属性值时触发
  // 参数target是目标对象
  // 参数property是要获取的属性名
  // 参数receiver是Proxy对象或继承Proxy的对象
  get(target, property, receiver){
    console.log('获取值')
  },
  // 陷阱函数,写入属性值时触发
  // 参数value是新的属性值
  set(target, property, value, receiver){
    console.log('设置值')
  },
  // 陷阱函数,删除属性值时触发
  deleteProperty(target, property){
    console.log('删除属性')
  }
}

// 目标对象
const target = {name: 'jack'}
// 为目标对象创建代理对象
const proxy = new Proxy(target, baseHandler)
// 读取属性值
proxy.name
// 设置属性值
proxy.name = 'tom'
// 删除属性
delete proxy.name

之后,针对代理对象的相关操作就会触发处理器对象中的对应陷阱函数,在陷阱函数中就可以为目标对象的属性访问添加自定义的业务逻辑。

上述代码的运行结果为:

获取值
设置值
删除属性