我们知道 Vue2.x 版本使用了 ES5 中的 Object.defineProperty 方法来实现响应式数据(数据双向绑定)。
实现原理:
如上图所示,存在数据data,遍历data。当获取data中任意属性值时,便执行get方法 控制台会打印出结果。
当给data中任意属性设置值时,便执行set方法控制台打印出最新的值
举个栗子:
当我们修改已存在的属性 name 和 color 时,页面显示发生了改变实现了数据响应,但当添加一个不存在 price 属性并赋值时,页面的‘价格’并没有成功被赋值,这就是 defineProperty 存在的问题,无法实时监测到添加或删除一个属性。不过vue已经通过内置方法$set,$delect 等解决了这个问题。
删除属性同理,使用 $delete,页面‘颜色’值消失,实现数据响应式
其中 defineProperty 对于数组下标和length属性的操作,也存在一些问题
直接通过下标方式添加一项值页面DOM并未改变
使用 $set 和 数组的方法就实现了
总结
存在缺点:
Object.defineProperty 无法监测到对象属性动态的添加和删除
Object.defineProperty 无法监测到数组下标和length属性的变更
解决方案:
Vue 提供了 $set 方法用于动态给对象添加属性
Vue 提供了 $delete 方法用于动态删除对象属性
重写vue中数组方法,用于监测数组的变更
Vue3.0抛弃了 Object.defineProperty 方法,使用ES6新增的 proxy 语法来实现响应式数据。
实现原理
当操作proxyData代理对象时,可以获取,可以设置,可以新增,可以删除
增删改查都能实现
举个栗子
我们在对data数据进行增删改查时,完全没有问题,并不需要特殊处理
即使面对数组也可是通过下标添加一个新的值
总结
优点:
proxy 可以监测到对象属性动态的添加和删除
proxy 可以监测到数组下标和length属性的变更
相对defineProperty 需要对数据遍历循环,proxy 的执行速度效率大大提升
存在缺点:
proxy 语法是ES6新出的功能,对于低版本浏览器不支持,不过vue3.0会针对IE11出一个特殊的版本来解决这个问题