vue2的响应式原理
用 object.defineProperty结合订阅者发布者模式进行数据劫持,并通过设置get和set方法对数据进行操作,设置值后在 get() 中向发布者添加该属性的订阅者,这里在编译模板时就会初始化每一属性的 watcher,在数据发生更新后调用 set 时会通知发布者 notify 通知对应的订阅者做出数据更新,同时将新的数据更新到视图上显示。
使用Object.defineProperty做响应式的缺点
有三点
1.深度监听,需要一次性递归到底,计算量比较大
2.描述符只有get和set,无法监听新增属性和删除属性的操作
3.无法原生监听数组
这三个缺点中,第二点是defineProperty本身API的缺陷,而第一点和第三点都是出于性能考虑而做的取舍
解决缺点的方法
当我们通过数组的方法去更改数组时或是直接删除data数据,数据并不能实现响应式,因为Object.defineProperty是没有办法处理属性删除和新增的
因此vue2的响应式,通过数组方法(prop,push),或是删除,vue是不能监听的
vue2中通过vue2中可以通过vue.datele和vue.set这些vue内置api来改变属性,实现响应式
在vue2中通过object.defineProperty实现响应式原理时新增属性、删除属性界面不会更新;直接通过下标修改数组,界面也不会自动更新
vue3
用proxy
1、对于基本类型的数据,响应式依然是靠Object.defineProperty()的get与set完成的。
2、对于对象类型的数据
通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
warch监听的是整个对象,数据发生改变就会直接实时视图更新