1. defineProperty 和 proxy 的区别
- Vue2.x 通过给每个对象添加
getter setter
属性去改变对象,实现对数据的观测,Vue3.x 通过 Proxy 代理目标对象,且一开始只代理最外层对象,嵌套对象lazy by default
,性能会更好 - 支持数组索引修改,对象属性的增加,删除
Vue 在实例初始化时遍历 data 中的所有属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。这样当追踪数据发生变化时,setter 会被自动调用。
Object.defineProperty 是 ES5 中一个无法声明的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
但是这样做有以下问题:
- 添加或删除对象的属性时,Vue 检测不到。因为添加或删除的对象没有在初始化进行响应式处理,只能通过
$set
来调用Object.defineProperty()
处理。 - 无法监控到数组下标和长度的变化。
Vue3 使用 Proxy 来监控数据的变化。Proxy 是 ES6 中提供的功能,其作用为:用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。相对于Object.defineProperty()
,其有以下特点:
- Proxy是对整个对象的代理,而Object.defineProperty只能代理某个属性。
- 对象上新增属性,Proxy可以监听到,Object.d