美文网首页
vue的setter的缺点

vue的setter的缺点

作者: meow_possion | 来源:发表于2019-06-30 22:43 被阅读0次

    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是无法监听到变化的
    • 直接用下标修改数组项的时候,不会被vue检测到
    • 修改数组的长度的时候,也不会被vue检测到
      Vue中只有七种数组操作的方法可以被检测到,分别是:push()、pop()、shift()、unshift()、splice()、reverse()、sort()。
      Vue的实现是对数组的这几个操作进行了hack,使之能够变成响应的属性。
      以上这几种方法也是数组方法中,会改变原数组的方法,其他方法不会。

    对象添加响应式属性

    为了弥补这种缺陷,可以用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有以下的优点:

    • 可以劫持整个对象,并且返回新的对象
    • 有13种劫持操作。核心
      proxy对象在ES2015规范中被正式发布,用于定义基本操作的自定义行为。(比如属性操作、赋枚举,函数调用等)。
    • Proxy是ES6的新特性,翻译过来是“代理”的意思,用在这里表示让他来代理某些操作。
      proxy能够让我们以简洁明了的方式控制外部对对象的访问,类似于设计模式中的代理。
    • Proxy可以理解为在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此可以用来对外界的访问进行过滤和改写
      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的时候采用了)

    相关文章

      网友评论

          本文标题:vue的setter的缺点

          本文链接:https://www.haomeiwen.com/subject/lmpjqctx.html