资讯专栏INFORMATION COLUMN

Vue3.0数据双向绑定Proxy探究

stormzhang / 1876人阅读

摘要:只能劫持对象的属性因此我们需要对每个对象的每个属性进行遍历。属性对于怎么拼接到和上面说到了怎么使用做数据劫持,怎么结合订阅发布,请结合数据双向绑定探究对照着数据劫持的部分去替换看一下。

前言

2018年11月16日,关注vue的人都知道这个时间点发生了什么事儿吧。vue3.0更新内容

研究数据双向绑定的大佬们都在开始猜测这个新机制了,用原生Proxy替换Object.defineProperty

1. 为什么要替换Object.defineProperty

替换不是因为不好,是因为有更好的方法使用效率更高

Object.defineProperty的缺点:

在Vue中,Object.defineProperty无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。为了解决这个问题,经过vue内部处理后可以使用以下几种方法来监听数组。有关于这个说明,可以看看这个文章 vue为什么不能检测数组变动

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

目前只针对以上方法做了hack处理,所以恰数组属性是检测不到的,有局限性。

Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue里,是通过递归以及遍历data对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象,不管是对操作性还是性能都会有一个很大的提升。
而要取代它的Proxy有以下两个优点:

1. 可以劫持整个对象,并返回一个新对象
2. 有13种劫持操作

2. 什么是Proxy
Proxy是 ES6 中新增的一个特性,翻译过来意思是"代理",用在这里表示由它来“代理”某些操作。 Proxy 让我们能够以简洁易懂的方式控制外部对对象的访问。其功能非常类似于设计模式中的代理模式。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

使用 Proxy 的核心优点是可以交由它来处理一些非核心逻辑(如:读取或设置对象的某些属性前记录日志;设置对象的某些属性值前,需要验证;某些属性的访问控制等)。 从而可以让对象只需关注于核心逻辑,达到关注点分离,降低对象复杂度等目的。

基本用法:

let p = new Proxy(target, handler);

参数:

target: 是用Proxy包装的被代理对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler: 是一个对象,其声明了代理target 的一些操作,其属性是当执行一个操作时定义代理的行为的函数。

p是Proxy对象,当其他操作对p进行更改的时候,会执行handler对象的方法。Proxy有13种数据劫持的操作,常用的handler处理方法:

get: 读取值,
set: 获取值,
has: 判断对象是否拥有该属性,
construct: 构造函数

给个例子:

let obj = {};
 let handler = {
   get(target, property) {
    console.log(`${property} 被读取`);
    return property in target ? target[property] : 3;
   },
   set(target, property, value) {
    console.log(`${property} 被设置为 ${value}`);
    target[property] = value;
   }
 }

 let p = new Proxy(obj, handler);
 p.name = "tom" //name 被设置为 tom
 p.age; //age 被读取 3

更多的Proxy属性方法参考MDN Proxy

3. Proxy实现数据劫持
observe(data) {
  const that = this;
  let handler = {
   get(target, property) {
      return target[property];
    },
    set(target, key, value) {
      let res = Reflect.set(target, key, value);
      that.subscribe[key].map(item => {
        item.update();
      });
      return res;
    }
  }
  this.$data = new Proxy(data, handler);
}

这段代码里把代理器返回的对象代理到this.$data,即this.$data是代理后的对象,外部每次对this.$data进行操作时,实际上执行的是这段代码里handler对象上的方法。
注:这儿用到了reflect属性,这也是ES6里面的,不知道的去这儿看看吧。reflect属性

4. 对于怎么拼接到watcher和compile

上面说到了怎么使用Proxy做数据劫持,怎么结合订阅发布,请结合 vue2.0数据双向绑定探究 对照着Object.defineProperty
数据劫持的部分去替换看一下。其他的设计思想估计跟之前的八九不离十。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100117.html

相关文章

  • 学习MVVM及框架的双向绑定笔记

    摘要:的数据劫持版本内部使用了来实现数据与视图的双向绑定,体现在对数据的读写处理过程中。这样就形成了数据的双向绑定。 MVVM由以下三个内容组成 View:视图模板 Model:数据模型 ViewModel:作为桥梁负责沟通View和Model,自动渲染模板 在JQuery时期,如果需要刷新UI时,需要先取到对应的DOM再更新UI,这样数据和业务的逻辑就和页面有强耦合。 在MVVM中,U...

    VioletJack 评论0 收藏0
  • 使用Proxy实现双向绑定

    摘要:取出所有属性遍历不允许绑定在非对象上进行数组操作时,会进行两次一次数据改变,一次改变,两次改变的值是不变,因此不应该多分发一次消息通知订阅者 前言:vue3.0要用Proxy来实现双向绑定,因此先来尝试一下实现方法。 1 Object.defineProperty 实现原来vue2的实现使用Object.defineProperty,监听set,但对于数组直接下标给数组设置值监听不了。...

    Yang_River 评论0 收藏0
  • Vue数据响应式原理笔记 就几行没啥可看的

    摘要:什么是数据响应式数据响应式既数据双向绑定,就是把绑定到,当我们用代码更新时,就会自动更新如果用户更新了的数据也自动本更新。数据响应式的原理实现数据响应式的原理就是利用了这个方法重新定义了对象获取属性值和设置属性值的操作来实现。 1、什么是数据响应式 数据响应式既数据双向绑定,就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新;如果用户...

    SillyMonkey 评论0 收藏0
  • 初识Proxy、Reflect

    摘要:主要原因应该是在处理数组响应是会存在缺陷。构造函数其中表示生成一个实例,为需要代理的对象,则是一个对象,定义了各种代理行为。对于满足条件的属性以及其他属性,直接保存报错报错拦截的操作,返回一个布尔值。 前言 https://segmentfault.com/a/11... Vue3.0应该马上就要发布正式版了。听说在新版本中,Proxy取代了Object.defineProperty进...

    gougoujiang 评论0 收藏0
  • 精读《Vue3.0 Function API》

    摘要:拿到的都是而不是原始值,且这个值会动态变化。精读对于的与,笔者做一些对比。因此采取了作为优化方案只有当第二个依赖参数变化时才返回新引用。不需要使用等进行性能优化,所有性能优化都是自动的。前端精读帮你筛选靠谱的内容。 1. 引言 Vue 3.0 的发布引起了轩然大波,让我们解读下它的 function api RFC 详细了解一下 Vue 团队是怎么想的吧! 首先官方回答了几个最受关注的...

    voyagelab 评论0 收藏0

发表评论

0条评论

stormzhang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<