Vue的学习之路--Vue的数据代理

目录

一、什么是数据代理?

二、数据代理的实现

1.基于 Object.defineProperty() 方法

2.数据代理实现的原理

三、数据代理的应用及其优势


一、什么是数据代理?

        数据代理是一种技术,通过代理、拦截对象属性及方法的访问请求,实现与该对象的交互。在Vue中,数据代理是指在Vue实例化一个组件时,Vue会将组件中的data属性中的数据转化为getter/setter,并将这些getter/setter注册到Vue的响应式系统中,在Vue实例中访问组件中的数据时,实际上是访问了这个getter/setter,它能统计出数据的依赖关系,并在数据变化时更新视图。

二、数据代理的实现

        这么光看概念,乍一看确实会有点摸不着头脑。我会结合例子来讲讲数据代理是怎么实现的。

1.基于 Object.defineProperty() 方法

        要清楚数据代理的底层实现,首先,我们必须得知道一个api,那就是Object.defineProperty()方法。

        参考MDN官方文档,我们知道,Object.defineProperty() 是 JavaScript 中一个用于定义对象属性的方法。它接受三个参数:要定义属性的对象,属性名和描述符对象。

        基本语法:

Object.defineProperty(obj, prop, descriptor)

其中:

  • obj:要定义属性的对象(目标对象)。
  • prop:要定义或修改的属性的名称(目标属性名)。
  • descriptor:一个对象,它定义了要定义或修改的属性的描述符。

描述符对象包含了四个可选属性:value、writable、enumerable 和 configurable:

  • value:属性的值。如果未定义,属性的默认值为 undefined。
  • writable:如果为 true,则属性值可以被赋值运算符改变;否则它是只读的。
  • enumerable:如果为 true,则属性会出现在对象的枚举属性中;否则不会。
  • configurable:如果为 true,则该属性描述符的配置可以更改,同时该属性也可以从对应对象中删除;否则它是不可配置的。

        这些属性具体的用法在这里我就不再赘述,如果有兴趣,可以去看看MDN的官方文档,里面对每个属性都有具体的示例去解释。我们直接来看看 Object.defineProperty()这个方法的作用。

let obj1 = {
  foo: ''
};

let obj2 = {
  bar: 'Hello World!'
};

Object.defineProperty(obj1, 'bar', {
  get: function() {
    return obj2.bar;
  },
  set: function(value) {
    obj2.bar = value;
  }
});

console.log(obj1.bar);     // 输出: 'Hello World!'
obj1.bar = 'Goodbye!';
console.log(obj2.bar);     // 输出: 'Goodbye!'
console.log(obj1.bar);     // 输出:'Goodbye!'

在这个demo中,我们定义了两个对象obj1和obj2,它们分别有着各自的属性foo和bar。

然后,我们通过Object.defineProperty()在对象obj1中定义了一个原本obj1没有的属性‘bar’

然后设置了一个getter和一个setter。

这个getter的作用是:当用户获取obj1.bar这个属性值的时候,返回的是obj2.bar的值,也就是把对象obj2.bar的值赋给了obj1.bar

这个setter的作用是:当用户修改obj1.bar时,就把修改后的值赋给obj2.bar。

通过setter和getter,我们就实现了数据代理。控制台打印结果如下所示:

 

那么这个结果是怎么来的呢?听听我的分析。

首先是第一个console.log(obj1.bar); 语句

因为用户要获取obj1.bar,所以就自动调用了getter,而get函数返回的值为obj2.bar的值,所以就打印了obj2.bar的值,为Hello World!。

然后是后面的语句:

obj1.bar = 'Goodbye!';
console.log(obj2.bar);     
console.log(obj1.bar);     

因为用户要修改obj1.bar的值为"Goodbye!",所以自动调用了setter,而set函数是把修改后的值赋给了obj2.bar,所以这时候打印obj2.bar,就会变成  Goodbye!

然后用户又要获取obj1.bar的值,这时候又要调用getter,把obj2.bar的值赋给obj1.bar,因为obj2.bar的值现在为 Goodbye!,所以打印出来的obj1.bar的值也为 Goodbye!

2.数据代理实现的原理

        现在我们知道了 Object.defineProperty() 的用法,那我们就来看看Vue中数据代理的实现原理是什么。

        在 Vue 实例化的过程中,Vue 会使用 Object.defineProperty() 给实例对象 data 中定义的每个属性都添加 getter 和 setter。这些 getter 和 setter 将实例属性访问代理到 data 对象中对应的属性上,这就实现了数据代理。

        这句话是什么意思呢?我们还是通过示例来理解:

        我们有这样的一个简单的模版

然后通过在控制台中查看vm实例的属性,我们可以看到一些端倪

 

我们并没有手动地去给days和months属性添加get和set函数,这都是Vue 使用了 Object.defineProperty() 给实例对象vm的 data 中定义的每个属性都添加 getter 和 setter。

这样,当用户修改data中的属性时,就会自动调用setter,改变视图中对应的属性值了。这就是数据代理的实现原理。

!!!注意:在实例化 Vue 对象时,Vue 会将传入的 data 对象的属性都添加到实例的 _data 对象中,并实现数据代理,使得这些属性能够被实例直接访问。如果没有_data对象,那么我们在模版中使用Vue实例中的data属性时,必须要在属性名前面加上_data.,所以Vue大大简化了我们的工作。

 

三、数据代理的应用及其优势

通过使用 Vue 框架的数据代理技术,我们可以实现简单、灵活、高效的数据绑定。借助于数据代理,可以实现以下优势:

  1. 实现自动依赖收集与响应

    在 Vue 中,当 data 中的数据发生变化时,Vue 可以自动侦测到相应的依赖并且刷新页面,从而实现数据的响应式更新。

  2. 提高代码的可读性

    通过代理,Vue 可以将数据与页面的操作进行相互绑定,从而实现数据的自动更新,避免了手动监听和更新数据的繁琐操作,使得代码更加简洁易读。

  3. 实现数据与视图的双向绑定

    Vue 中的数据代理技术可以将数据与视图进行双向绑定,从而实现了数据的自动同步,使得数据的维护更加方便。

总的来说,Vue 数据代理是 Vue 框架中非常重要和核心的特性,可以提高代码编写的高效性和可读性。它通过对对象的访问进行代理与拦截,实现数据绑定与自动更新,使得开发流程更加高效并且方便维护。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值