vue data里的数据的变化

实际在开发过程中发现,我们打印data里的数据的时候会发现,他不是我们所看到的以往的很平常的格式,他是一个proxy的格式的,如下图:

 也就是说无论是什么类型的数据,都会在外面包一层proxy的包装;

这个是作什么的呢?

查资料——————————————

经过这一顿操作之后,数据就可以恢复正常的类型了,

JSON.parse(JSON.stringify(val))

关于Proxy:

Proxy可以理解成,在目标对象之前架设一层 "拦截",当外界对该对象访问的时候,都必须经过这层拦截,而Proxy就充当了这种机制,类似于代理的含义,它可以对外界访问对象之前进行过滤和改写该对象。

如果对vue2.0了解或看过源码的人都知道,vue2.0中使用 Object.defineProperty()方法对该对象通过 递归+遍历的方式来实现对数据的监控的,

当我们使用数组的方法或改变数组的下标是不能重新触发 Object.defineProperty中的set()方法的,因此就做不到实时响应了。所以使用 Object.defineProperty 存在如下缺点:

1. 监听数组的方法不能触发Object.defineProperty方法中的set操作(如果要监听的到话,需要重新编写数组的方法)。
2. 必须遍历每个对象的每个属性,如果对象嵌套很深的话,需要使用递归调用。

 但是vue2.0就是用$set()方法去解决上面的这个问题,Vue3.0呢进行了升级,那就是Proxy。

Proxy基本语法

const obj = new Proxy(target, handler);

这里就和上面的截图对应上了,有木有发现呢~,再来一个详细的图;

参数说明如下:

target: 被代理对象。
handler: 是一个对象,声明了代理target的一些操作。
obj: 是被代理完成之后返回的对象。

但是当外界每次对obj进行操作时,就会执行handler对象上的一些方法。handler中常用的对象方法如下:

1. get(target, propKey, receiver)
2. set(target, propKey, value, receiver)
3. has(target, propKey)
4. construct(target, args):
5. apply(target, object, args)

如下代码演示:

const target = {
  name: 'kongzhi'
};

const handler = {
  get: function(target, key) {
    console.log(`${key} 被读取`);
    return target[key];
  },
  set: function(target, key, value) {
    console.log(`${key} 被设置为 ${value}`);
    target[key] = value;
  }
};

const testObj = new Proxy(target, handler);

/*
  获取testObj中name属性值
  会自动执行 get函数后 打印信息:name 被读取 及输出名字 kongzhi
*/
console.log(testObj.name);

/*
 改变target中的name属性值
 打印信息如下: name 被设置为 111 
*/
testObj.name = 111;

console.log(target.name); // 输出 111

如上代码所示:也就是说 target是被代理的对象,handler是代理target的,那么handler上面有set和get方法,当每次打印target中的name属性值的时候会自动执行handler中get函数方法,当每次设置 target.name 属性值的时候,会自动调用 handler中的set方法,因此target对象对应的属性值会发生改变,同时改变后的 testObj对象也会发生改变。同理改变返回后 testObj对象中的属性也会改变原对象target的属性的,因为对象是引用类型的,是同一个引用的。如果这样还是不好理解的话,可以简单的看如下代码应该可以理解了:

const target = {
  name: 'kongzhi'
};

const testA = target;

testA.name = 'xxx';

console.log(testA.name); // 打印 xxx

console.log(target.name); // 打印 xxx

大概就是这样的,vue3.0的升级,可直接监听数组类型的数据变化
监听的目标为对象本身,不需要像Object.defineProperty一样遍历每个属性,有一定的性能提升。

posted @ 2021-08-20 13:50  之鹿喵  阅读(849)  评论(0编辑  收藏  举报