前言

上一篇文章 Vue学习——【第三弹】 中我们了解了MVVM模型,这篇文章接着学习Vue中的数据代理

简单介绍

数据代理就是**一个对象(A)来代理对另一个对象(B)的属性操作(A一定要包含B)。**直接看定义大家可能觉得有些抽象,我们可以用代码来实现。

提到数据代理,我们会很容易想到一个重要的API:JavaScript中的Object.defineProperty() 方法

通过对JavaScript的学习,我们知道可以用Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性,它的语法是这样的:

Object.defineProperty(obj, prop, desc)

obj 需要定义属性的当前对象
prop 当前需要定义的属性名
desc 属性描述符

该方法的工作机制:
给对象添加属性值 value
给对象添加getter和setter
gettersetter用于对属性的读写进行监控

并且该方法还具有一些配置项,比如:

 enumerable:true,//enumerable用于控制属性是否可以枚举,默认值时falsewritable:true,//该配置项可以控制属性是否可以被修改,默认是falseconfigurable:true//该配置项可以控制属性是否可以被删除,默认值是false

那么接下来我们就来看看Object.defineProperty() 方法的使用方式:

 <!-- 数据代理:通过一个对象代理对另一个对象中的属性进行操作 --><script type="text/javascript">let obj1 = {a:100}let obj2 = {b:200}// 当访问obj2.a的时候,就调用get函数,然后返回obj1中的属性a;当修改obj2.a时,obj1.a就会被修改Object.defineProperty(obj2,'a',{get(){console.log('obj1.a被读取')return obj1.a},set(value){console.log('obj.a被修改')obj1.a = value}})</script>

在控制台上操作:

Vue中的数据代理

我们知道Vue是渐进式的JavaScript框架,而Vue中的数据代理所调用的API就是Object.defineProperty() 方法,我们举几个例子,来观察一下Vue中的数据代理的实现:

<div id="demo"><h1>姓名:{{name}}</h1><h2>地址:{{address}}</h2></div><script type="text/javascript">const vm = new Vue({el:'#demo',data:{name:'小明',address:'山东'}})</script>

控制台上操作:

我们在控制台发现了熟悉的两个属性——name和address,并且点开它们我们可以看到它们的值就是我们代码中的值;

前文提到使用Object.defineProperty() 方法时,getter() 和setter() 用于对属性的读写进行监控,我们不妨来验证一下Vue数据代理中的getter()和setter()

捕获data

在验证setter()函数的调用之前,我们先看一下如何去获取data:

当我们直接去获取data时发现控制台返回 undefined

这时候我们看一下我们写的代码:

    <div id="demo"><h1>姓名:{{name}}</h1><h2>地址:{{address}}</h2></div><script type="text/javascript">const vm = new Vue({el:'#demo',data:{name:'小明',address:'山东'}})</script>

我们不难看出,vm中的data其实是vm配置对象中的一个属性,并非全局变量,因此我们无法通过vm.data直接获取data,这时候想要获取data,就需要用到vm._data进行获取:

并且我们发现,在vm._data中还出现了data中的name和address属性。

其实,这里的vm._data就是我们想要获取的data,比如我们举个例子来验证一下:

我们将含有name和address属性的data作为一个全局变量写在 vm 的外部,然后在Vue实例中写上一个data;再在控制台比较vm._data是否和data相同,结果是返回true,很明显,两者是相同的。

简单描述一下Vue中的数据代理的过程:
vm 拿到data中的数据后,放在了vm里的_data中。vm中的name和address代理了_data中的name和address。读取vm.name时,调用getter()方法,读取了_data中的name。
修改了vm中的name时,就会调用setter()方法去修改_data中的name。
如果不做代理,在“{{ }}”中须要这样写成“{{_data.xxx}}”的形式;通过Vue中的数据代理,我们就可以简化缩写内容,只需要些{{xxx}}的形式即可。

明白以上原理,我们就可以很容易明白在进行数据代理时对getter()和setter()的调用啦。

getter()

在我们读取vm中的name属性时,负责对name进行读取的函数getter()就会被调用,然后执行对data中的name属性值进行读取。

setter()

并且在模板中的花括号里的内容我们都可以写成 _data.xxx 的形式,通过Vue的数据代理,我们就无需如此繁琐的写成_data.xxx的形式。

小结

通过代码的验证,下图可以为我们展现出Vue中的数据代理机制:

参考文献

Vue官方文档
MDN官方文档
Vue技能树
B站视频讲解

如有不足,感谢指正!

Vue学习——【第四弹】相关推荐

  1. Vue 学习第四天--第一部分 --盲点整理与昨天知识回顾

    Vue   学习第四天--第一部分 1.父组件向子组件传值 v-bind:临时变量名="父组件变量名" v-bind:value="fathervalue" 子 ...

  2. Vue学习——【第二弹】

    前言 上一篇文章 Vue学习--[第一弹] 中我们学习了Vue的相关特点及语法,这篇文章接着通过浏览器中的Vue开发者工具扩展来进一步了解Vue的相关工作机制. Vue的扩展 我们打开Vue的官方文档 ...

  3. Vue 学习第四天 -2

    4. Vue  操作Dom ,获得Dom节点,  ref 属性, $refs ref 引用组件 ,然后实现相关数据和 方法的引用,差不多就是父组件调用子组件, <body> <!-- ...

  4. Vue学习(四)—— vue中的ajax

    文章目录 第四部分 vue中的ajax 一.axios 1.安装 2.引入 二.vue脚手架配置代理 1.方法一 2.方法二 三.github用户搜索案例 1.接口地址 2.vue 项目中常用的 2 ...

  5. 统计学习第四弹--随机变量的概率分布

    关于随机变量概率分布的重要概念: 概率:对事件的发生的可能性大小的度量值 随机变量:事先不能确定其取值的变量 离散型随机变量:只能取有限个值的随机变量 连续型随机变量:可以取一个或多个区间中任何值的随 ...

  6. sleep期间读取所有_java并发学习第四弹:走进JDK源码去了解sleep和join

    sleep方法详解: 作用:我只想让线程在预期的实际执行,其他时间不要占用CPU资源 特点: 1.sleep不释放锁,包括synchronized和lock和wait有很大不同 public clas ...

  7. VUE学习(十四)读取json文件

    1.json文件内容 2.使用import导入json <script setup>import config from '../../public/config/config.json' ...

  8. MySQL学习第四弹——多表查询分类以及案例练习源码详解

    多表查询(续) 连接查询 内连接: 相当于查询集合A与集合B的交集部分 外连接 左外连接:查询左表所有数据,以及两张表交集部分数据 右外连接:查询右表所有数据,以及两张表交集部分数据 自连接:当前表与 ...

  9. vue 学习笔记第无弹

    1. 在 webpack 中配置 .vue 组件页面的解析 运行cnpm i vue -S将 vue 安装为运行依赖: 运行cnpm i vue-loader vue-template-compile ...

  10. 千峰java 笔记整理_JAVA学习笔记系列:菜鸟Vue学习笔记(四)

    菜鸟Vue学习笔记(四) 上周学习了使用Vue来操作表单元素进行数据双向绑定,今天我们来学习下Vue中的组件,Vue中的组件作用就是去封装一些常用的页面标签,将其当做一个整体,以便在其他位置直接使用一 ...

最新文章

  1. 指定的文件不是虚拟磁盘 没有快照_vmware workstaiton 15 虚拟机克隆(4)
  2. ubuntu+eclipse+svn
  3. 序列输出ZOJ1108 FatMouse's Speed
  4. Introducing DataFrames in Apache Spark for Large Scale Data Science(中英双语)
  5. 【JZOJ3824】【NOIP2014模拟9.9】渴
  6. ssh 免密码登录---问题
  7. kalman filter using python
  8. Linux使用进程id跟踪程序,使用linux的pidof命令返回运行程序的进程ID
  9. allennlp 版本关系
  10. 后缀树(一)定义及构造
  11. 感性电路电流计算_电路理论——关于复功率的一些常见问题
  12. javaweb基础打卡17
  13. Premiere cs6导出MP4格式视频
  14. SAS 方差分析(复习4)
  15. 小白学习MySQL - MySQL会不会受到“高水位”的影响?
  16. R语言ggpubr包的ggscatter函数可视化散点图(scatter plot)、设置add参数为loess为散点图添加局部加权回归曲线、配置conf.int参数为回归线添加置信区
  17. 51nod3431 取石子游戏
  18. 使用FileOutPutStream下载docx文件报文件已损坏解决
  19. PLC的面向对象编程
  20. 【MySQL】mysql数据库操作指南

热门文章

  1. 人工智能 漆桂林_领域专家走进平安科技(PA Tech),共议知识图谱为医疗AI赋能路径...
  2. 电子书 鸟哥的Linux私房菜 (基础学习篇 第三版).pdf
  3. 华为手机有线共享网络_华为手机怎么投屏到电视?这2个方法又快又简单
  4. ps2019布尔运算快捷键_PS中的布尔运算如何使用-百度经验
  5. python股票量化交易(11)---使用pyqt5构建股票交易软件主页
  6. exFAT文件系统2
  7. dct变换的主要优点有哪些_数字图像处理(三)—— 离散余弦变换
  8. Android 绘图基础:Bitmap(位图)与Matrix(矩阵)实现图片5种操作(平移、旋转、错切、缩放、对称)
  9. 魔力魔力哟部署与安装文档
  10. HTML5里video标签支持哪些格式的视频文件