返回

vue2与vue3响应式原理之defineProperty和proxy深入浅出

前端

响应式系统概述:

响应式系统是一种在数据发生变化时,自动更新相关UI元素的技术。它是一种数据驱动方式,可以简化UI开发,实现数据的自动更新,提高开发效率。

Vue响应式系统原理:

Vue的响应式系统分为两部分:defineProperty和Proxy。defineProperty是ES5中定义属性的方法,而Proxy是ES6中引入的新特性。两者都可用于实现响应式系统。

defineProperty原理:

defineProperty方法允许您添加、修改或删除对象的属性,并为属性定义getter和setter方法。

defineProperty的基本用法如下:

Object.defineProperty(obj, prop, descriptor);

其中:

  • obj是目标对象。
  • prop是要定义的属性名称。
  • descriptor是属性的符,它是一个对象,可以包含以下属性:
    • value:属性的值。
    • writable:属性是否可写。
    • enumerable:属性是否可枚举。
    • configurable:属性是否可配置。

Proxy原理:

Proxy对象是一个代理对象,它可以拦截对另一个对象的访问,并自定义这些访问行为。

Proxy的基本用法如下:

const proxy = new Proxy(target, handler);

其中:

  • target是目标对象。
  • handler是一个对象,它定义了如何拦截对目标对象的访问。

Vue2和Vue3的响应式系统对比:

Vue2中,响应式系统使用defineProperty来实现。当对象的属性发生变化时,defineProperty会触发getter和setter方法,从而通知Vue进行更新。

Vue3中,响应式系统使用Proxy来实现。Proxy可以拦截对对象的访问,并在访问时触发getter和setter方法,从而通知Vue进行更新。

Proxy相对于defineProperty具有以下优势:

  • 性能更好。
  • 支持更多的数据类型,包括数组和Map。
  • 浏览器兼容性更好。

手写注册响应式方法:

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log('get', key);
      return val;
    },
    set(newVal) {
      console.log('set', key, newVal);
      val = newVal;
    }
  });
}

这个方法可以将对象的属性注册为响应式属性,当属性发生变化时,会触发getter和setter方法,从而通知Vue进行更新。

总结:

defineProperty和Proxy都是实现响应式系统的方法,Vue2和Vue3都使用了这两种方法。Proxy相对于defineProperty具有更好的性能和浏览器兼容性,因此Vue3采用了Proxy来实现响应式系统。