Vue2.0中的数据代理

🌵 作者主页:仙女不下凡

🌵 前言介绍:以下👇 内容都是我个人对于前端知识的总结,会定期更新欢迎持续关注!

🌵 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

🌵 学习理由:相信有很多小伙伴有个疑问,数据代理这个概念其实在开发中并不直接使用,为什么还要了解呢?相信很多小伙伴并不想只把前端开发的能力停留在会用这个层面上,了解这个原理有利于解决开发跟多疑问,同时这个原理也是面试的经典问题。


💛1.Object.defineProperty()方法

🌼学习数据代理之前先复习一个方法Object.defineProperty使用该方法给对象添加属性能够有更加细致的控制 🔊比如:可以控制追加在对象中的元素是否可以用forEach()等遍历;添加之后是否可以删除等,所以在Vue数据劫持数据代理计算属性都利用了该方法。
🌼下面就提两个需求简单体会一下Object.defineProperty()的实际应用。

🔔需求一:添加age属性并控制是否可以被枚举等功能👇
🔔需求二:添加number的值到height属性中,且number改变时height的值同步更改👇

<script type="text/javascript">
  let number = 160
  let person = {
    name: '张三',
    sex: '男'
  }

  Object.defineProperty(person,'age',{
    value:18,
    enumerable:true,  /控制属性是否可以枚举, 默认值是false/
    writable:true,  /控制属性是否可以被修改, 默认值是false/
    configurable:true,  /控制属性是否可以被删除, 默认是false/
  })

  Object.defineProperty(person,'height',{
    /当读取person的height属性时, get函数就会被调用, 且返回值就是height的值/
    get:function(){ return number},  //这样height值就可以时时随着number改变, 简写get(){}
    /当修改person的height属性时, setter就会被调用, 且收到修改的具体值/
    set(val){ console.log('收到height具体值为',val) }
  })
</script>

🌼get函数别称是getterset函数别称是setter


💛2.数据代理基本理念

🌼什么是数据代理?:通过一个对象代理对另一个对象中属性的操作(读/写)。

<script type="text/javascript">
  /用一段代码解释一下什么是数据代理, 将obj2数据交给obj代理/
  let obj = {x;100};
  let obj2 = {y:200};
  
  Object.defineProperty(obj2,'x',{
    get(){ return obj.x },
    set(value){ obj.x = value }
  })
</script>

💛3.数据代理在vue的data中的应用

💦Ⅰ.验证data中的数据代理

🌼下面就写了一段代码来验证vue中存在的数据代理是否成立,即图中settergetter两条线,如下图中💙蓝色和💗红色的线。

<body>
  <div id="root">
    <h2>学校名称: {{name}}</h2>  
    <h2>学校地址: {{address}}</h2>
  </div>
</body>
<script type="text/javascript">
  Vue.config.productionTip = false;  /阻止vue在启动时生成生产提示/
  
  const vm = new Vue({
    el:'#root',
    data:{    /vm._data就是这个里面的data,它做了一个数据劫持/
      name:'尚硅谷',
      address:'上海'
    }
  })
  console.log(vm,"打印vm为了便于观察");
  /执行结果为Vue实例, 其中data中每个数据(如name,address)都有自己的getter与setter/
</script>

数据代理
🌼下面的代码验证了vm._data就是这个里面的data,而在vm._data内部做了一个数据劫持

<body>
  <div id="root">
    <h2>学校名称: {{name}}</h2>  /所以如果vue中没做数据代理{{name}}就得写成{{_data.name}}/
    <h2>学校地址: {{address}}</h2>
  </div>
</body>
<script type="text/javascript">
  Vue.config.productionTip = false;  /阻止vue在启动时生成生产提示/
  let data = {
    name:'尚硅谷',
    address:'上海'
  }
  
  const vm = new Vue({
    el:'#root',
    data
  })
  console.log(vm._data === data);
  /执行结果为true, 所以vm._data就是data, 蓝色的线就可以验证了/
</script>

🌼如果vue中没做数据代理{{name}}就得写成{{_data.name}},令编码更加方便,这就是数据代理在Vue中的实际应用意义。
🌼因为当我们修改data中的值,页面上面的显示值同步修改,这就验证了红色线可以成立。

💦Ⅱ.Vue数据代理过程图形演示

数据代理
🌼🌼数据代理生成过程🌼🌼
❶当我们声明vue实例对象之后,即vm
vm中会生成各种配置对象options,其中options包含了_data
❸由于底层代码的支持会自动给_data中每个数据,在_data的外部(即同级)添加对应新的元素(即数据代理),如上图☝🏻中的name、address,同时每个name、address中都会有setter、getter函数。

vm {
  ......
  _data:{ __ob__: Observer },  /这里面存着name与address的值/
  ......
  name: '尚硅谷',
  address: '上海',
  ......
  get name: f proxyGetter,
  set name: f proxySetter,
  get address: f proxyGetter,
  set address: f proxySetter,  /这个就是添加的getter与setter方法/
  ......
}

💦Ⅲ.总结

🌼⑴Vue中的数据代理:通过vm对象代理data对象中属性的操作(读/写)。
🌼⑵Vue中数据代理的好处:更加方便的操作data中的数据。
🌼⑶基本原理: ❶通过Object.defineProperty()data对象中所有属性添加到vm上; ❷为每一个添加到vm上的属性,都指定一个getter/setter; ❸在getter/setter内部去操作(读/写)data中对应的属性。


💛4.数据代理在计算属性component中的应用

💭💭💭思考一个问题,已经有methods{{}}插值表达式,为什么还有components?有什么存在的意义呢?
👉解答:首先插值表达式{{}},在vue定义原则中曾注明只包含简单的表达式;其次当data中数据改变就会重新解析模板,也会再次调用相关方法methods,导致效率不高。

🌼 计算属性定义:要用的属性不存在,要通过已有属性计算得来。
🌼 计算属性原理:底层借助了Object.defineproperty()提供的gettersetter
🌼 计算属性中的 get函数什么时候执行? ❶初次读取时会执行一次❷当依赖的数据发生变化时会被再次调用。
🌼 计算属性的优势:与methods实现相比,内部有 缓存机制(复用),效率更高,调试更方便。

/什么是缓存解释一下/
{{fullName}}  /这里fullName多次复用了, fullName直接调用缓存的info的值, 这个就是缓存机制/
{{fullName}}
{{fullName}}

computed:{
  fullName:{
    /get作用:当有人读取fullName时,get就会被调用,且返回值就作为fullName的值/;
    /get什么时候被调用? ❶初次读取fristName时 ❷所依赖的数据发生改变时/
    get(){return this.info = 2},
    set(){},  /set什么时候调用? 当fullName被修改时调用, 不是必须写/
  }
}
/如果不用写set(),直接简写/
fullName:{return this.info = 2}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值