vue的setter的缺点

2019-06-30  本文已影响0人  meow_possion

Vue双向数据绑定的原理是基于发布者订阅者的模式,利用初始化的时候用Object.defineProperty劫持数据对象及其子对象的属性,为他们添加getter/setter,在触发setter的时候,就能收到通知,触发相应的更新函数,从而更新视图。
那么vue的数据绑定的缺点应该从原理去入手,

  1. Vue只有在初始化的时候才会劫持数据对象的getter、setter
    这就导致了我们必须在data选项中提前声明我们想要双向数据绑定的数据,无法添加根级别的响应数据。

  2. Vue劫持数据对象的getter、setter是利用了Object.defineProperty这个函数,那么这个函数的缺点即是vue双向数据绑定的缺点。
    Object.defineProperty无法监听到添加属性、删除属性等的操作,并且无法监听数组的变化(有资料显示Object.defineProperty可以监听数组的变化,但是vue中不对数组进行监听)。
    Object.defineProperty只能劫持对象的属性,而不能劫持整个对象,因此需要对对象的所有属性进行遍历,如果属性也是对象的话,那么要进行深度的遍历。
    表现为:

对象添加响应式属性

为了弥补这种缺陷,可以用Vue.set()方法,改方法可以为对象添加响应式属性,在实例上可以用vm.$set(),或者可以使用Object.assign()方法返回一个新的对象。

Vue.set(obj, propertyName, value);
vm.$set(obj, propertyName, value);
obj = Object.assign({}, obj, {a:xxx})

数组的响应式检测

弥补数组的缺陷可以用Vue.set(),也就是vm.$set()方法,也可以用数组的原生方法splice();

Vue.set(arr, index, value);
vm.$set(arr, index, value);
arr.splice(index, 1, value);

proxy和Object.defineProperty

基于Object.defineProperty只能劫持对象的属性,因此我们需要对对象进行递归遍历。
而取代它的proxy有以下的优点:

proxy的基本用法

 let p = new Proxy(target, handler);

target可以说任何类型的对象,包括原生数组、函数甚至另一个代理。
handler是一个对象,其声明了代理target的一些操作,其属性是当执行一个操作时,定义代理行为的函数。
p是代理之后的对象,每当对p有一些操作的时候,就会执行handler对象上的方法。Proxy有13种劫持操作,handler常用的代理操作如下:

get 读取操作
set 修改
has 判断对象是否有该属性
construct 构造函数

我们可以这样认为:proxy是Object.defineProperty的全方位加强版
Proxy有13种拦截方法,不限于apply、ownKeys、deleteProperty、has等等,是Object.defineProperty所不具备的
Proxy做为新特性,将做为浏览器厂商持续优化的重点。
Proxy的缺点是浏览器兼容性的问题,并且无法用polyfill磨平(所以vue2.x才没有采用,3.0的时候采用了)

上一篇 下一篇

猜你喜欢

热点阅读