vue2.x实现双向数据绑定的原理是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
它接收三个参数,要操作的对象,要定义或修改的对象属性名,属性描述符。重点就是最后的属性描述符。
属性描述符是一个对象,主要有两种形式:数据描述符和存取描述符。
这两种对象只能选择一种使用,不能混合两种描述符的属性同时使用。上面说的get和set就是属于存取描述符对象的属性。
然后我们可以通过在存取描述符中的get和set方法内写入自定义的逻辑来实现对象获取属性和设置属性时的行为
vue2.0 双向数据绑定的局限性:
1.如果属性不存在,默认后增加的数据不会更新到视图
2.数组不能通过长度修改,也不能通过数组的索引修改
3.Object.defineProperty不能对数组进行操作(vue内部只是对数组的所有方法进行重写数据劫持,但是对数组的长度和索引的变化没有进行相应的操作,所以才会出现这种局限性,$set来解决)
Vue3.x是用ES6的语法 Proxy对象来实现的,也可以用来实现数据劫持
相比于vue2.x,使用proxy的优势如下
1 defineProperty只能监听某个属性,不能对全对象监听
2 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)
3 可以监听数组,不用再去单独的对数组做特异性操作
4 vue3.x可以检测到数组内部数据的变化