上面刚刚讲完 Vue 监听对象的改变,接下来本应该说说数组的监听过程,但是在这里需要插播一节 Vue.set() ,这是因为 Vue.set() 与对象的连接较为紧密,所以串联在一起方便理解。

1、首先,定义一批数据用来渲染到页面上展示

<body><div id="root"><h2>姓名:{{student.name}}</h2><h2>年龄:真实{{student.age.realAge}} 虚拟{{student.age.virtualAge}}</h2><h2>性别:{{student.sex}}</h2></div><script>Vue.config.productionTip = falseconst vm = new Vue({el: '#root',data() {return {student: {name: 'al',age: {realAge: 27,virtualAge: 25}}}},})</script>
</body>

 2、页面展示完成之后,我发现页面上的性别属性没有展示出来,看了代码之后才知道是性别属性 sex 在初始化的时候没有定义。那我们想让 sex 属性展示出来应该怎么办呢?

如果是在初始化的过程中我们直接将 sex 属性添加到 data 中,那么在组件编译之后,sex 属性时可以直接展示在页面上的,但是如果现在不能在 data 中直接添加这个属性,那要怎么办呢?

首先想到的是,在控制台中去添加这个属性,因为我们已经使用 vm 接收到了这个 Vue 实例,所以可以直接对 该实例做操作。例如:

我们通过 vm实例._data( vm._data在初始化过程中,通过Object.defineProperty()) 将原本的 data 中定义的属性全部收集加工成为了响应式的属性)中的 student 对象中添加了一个 sex 属性,添加完了之后发现页面上并没有渲染性别字段,查看 vm._data 之后发现,虽然将 sex 属性添加到了 student 之中,但是这个属性很明显是没有被加工成响应式的,因为没有get 和 set 函数。因为 Vue 的数据代理模式,我们也可以直接在 vm 上访问到这个属性

但是也可以发现,在vm实例上的 sex 属性,和vm._data 中的是一样的,都不是响应式的。

如果我们不在 vm._data 上添加 sex属性,而是直接在 vm.student 上添加发现还是不会生效

而且实际上这个操作( 直接向 vm 上添加属性 )是错误的,虽然页面是不会报错的,但是我们需要知道的是,vm上的 student 实际上就是由于 Vue的数据代理,从 _data 上拿过来的。所以通过 vm._data 来改还说的过去,但是直接在vm上改就离谱了。

那么我就是要添加这个sex属性,还能在页面上展示,且我改变了这个属性的值之后,页面同样会重新渲染,有什么办法呢?

Vue.set():添加响应式属性 

我们通过在 vm._data 上添加属性或直接在vm上添加属性发现都是不好使的,那这个时候 Vue 就很贴心的帮我们提供了一个方法,使用 Vue.set() 添加的属性,同样会被 Vue 加工成响应式。

我们在控制台上直接输入这个方法,然后会发现这个方法提示了我们需要三个参数

target:需要向哪个目标对象添加

key:需要添加的属性名

val:需要添加的属性的值

在我向 vm._data.student 中添加了 值为 男 的 sex 属性之后,我们发现页面上展示了设置的值,查看 vm._data 发现,此时的 sex 已经成为了响应式数据,拥有了 get 和 set 方法

当我们改变 sex 的值时,页面也会同步更改

我们在使用 set 方法时 target 传递的是  vm._data.student ,但是实际上可以使用 vm.student,这是因为 Vue 的数据代理之后  vm._data.student === vm.student ,我们只是想取到 student 这个对象,是可以直接从 vm 上拿到的,只是不要像上面说那样,直接往 vm 上添加属性。

 vm.$set()

vm.$set() 这个方法 和 Vue.set()  方法的作用完全一样,只不过一个是挂载在 Vue上的全局api,一个是挂载在 vm实例上

 局限性

但是,这两个方法都是存在局限性的。

官网上是这么解释的,那这到底是个什么意思呢,我们来验证一下,把上面那个例子简化一下

<body><div id="root"><h2>姓名:{{user.name}}</h2><h2>地址:{{address}}</h2></div><script>Vue.config.productionTip = falseconst vm = new Vue({el: '#root',data() {return {user: {name: 'al',}}},})</script>
</body>

此时,页面上有一个地址展示,但是在 data 内部,我并没有定义一个 address 属性,所以页面无法展示具体地址

且页面报错了

这个错误的大致意思就是,address 属性没有在 data 内被定义,然后就在实例上使用了,这个错误肯定是正常的,因为 访问一个对象内部不存在的属性,默认值为undefined,Vue也不会展示该属性值,但是如果这个属性直接定义在 data 最外层的,类似这个 address ,那肯定是会报错的,因为这相当于访问了一个 undefined.address 。

那这个错误是正常的,我们就先不管他了,接下来我们要像上面一样,添加一个 address 属性,但是这时候要注意了,我们的 address 添加的位置,不是想 sex 一样 添加在深层对象内部的,而是直接添加在 data 最外层的,这样才不会造成读取不到数据,所以我们需要添加到 vm._data 中

但是,添加之后却出了问题,说的是:避免在运行时向 Vue 实例或其根 $data 添加响应式属性 - 在 data 选项中预先声明它。

那我不像 vm._data 中添加,我直接像 vm 上添加是个啥情况

还是同样的问题,那这个方法不是没用了么,那还咋添加数据啊,难道非要在初始化的时候在 data 内定义这个属性么?那这也太不方便了。 这个时候我们来仔细看一下这个错误说的是个啥。

简而言之就是不要向 vm实例对象中添加属性 或 直接向 vm._data 中添加属性。

回想一下上面的 sex 案例,我们是在 vm._data.student 这个对象中添加了 sex 属性,而不是直接在 vm._data 中添加的,那我们按照这个思路来处理一下,把 address 这个属性不要直接放在 _data 的最外层,我们把它包起来

<body><div id="root"><h2>姓名:{{user.name}}</h2><h2>地址:{{info.address}}</h2></div><script>const vm = new Vue({el: '#root',data() {return {info: {},user: {name: 'al',}}},})</script>
</body>

包起来之后,我们再尝试向 vm.info 中添加 address属性 ,发现此时是成功的 ,且 address 也是响应式的属性。

总结

1、如果我们在初始化之后想要添加一个响应式数据,可以使用 set 方法,改方法传递三个参数,分别是:targe( 需要向哪个目标对象中添加 ),key( 添加的属性 ),val( 属性的值 )

2、Vue.set() 和 vm.$set() 这两个方法的作用一样,传参也一样,不一样的是一个是挂载在Vue上的全局api,一个是挂载到 Vue实例对象上的方法

3、使用 set() 方法添加属性时,不能直接添加到 vm实例对象上,也不能直接添加到根数据data中,需要添加到 data 中的某一个对象上才能生效

4、因为Vue的数据代理,所以我们在使用 set() 方法时,获取目标对象时,可以使用 vm.xxx,也可以使用 vm._data.xxx

Vue-Vue.set() 的原理及使用相关推荐

  1. 【重学Vue】数据响应原理真的是双向绑定吗?

    最近 Ant Design Vue 作者 - 唐金州,在某平台开课了,在整个课程中系统的讲述了Vue的开发实战.在第八讲中介绍了Vue双向绑定的问题,这里我整理一些资料客观的分析一下 Vue数据响应原 ...

  2. vue created 调用方法_深入解析 Vue 的热更新原理,偷学尤大的秘籍?

    大家都用过 Vue-CLI 创建 vue 应用,在开发的时候我们修改了 vue 文件,保存了文件,浏览器上就自动更新出我们写的组件内容,非常的顺滑流畅,大大提高了开发效率.想知道这背后是怎么实现的吗, ...

  3. vue指令写在html中的原理,详解Vue中的MVVM原理和实现方法

    对Vue中的MVVM原理解析和实现首先你对Vue需要有一定的了解,知道MVVM.这样才能更有助于你顺利的完成下面原理的阅读学习和编写下面由我阿巴阿巴的详细走一遍Vue中MVVM原理的实现,这篇文章大家 ...

  4. 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分

    最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...

  5. Vue.js响应式原理

    Vue.js响应式原理 框架 浏览数:659 2017-9-20 关于Vue.js Vue.js是一款MVVM框架,上手快速简单易用,通过响应式在修改数据的时候更新视图.Vue.js的响应式原理依赖于 ...

  6. vue双向数据绑定的原理

    有关双向数据绑定的原理 最近两次面试的时候,被问到了vue中双向数据绑定的原理,因为初学不精,只是使用而没有深入研究,所以答不出来.之后就在网上查找了别人写的博客,学习一下. 下面是博客园一篇博客,以 ...

  7. vue的双向绑定原理及实现

    前言 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue的双向绑定版本,先上个成果图 ...

  8. vue render函数_Vue原理解析(一):Vue到底是什么?

    Vue,现在前端的当红炸子鸡,随着热度指数上升,实在是有必要从源码的角度,对它功能的实现原理一窥究竟.个人觉得看源码主要是看两样东西,从宏观上来说是它的设计思想和实现原理:微观上来说就是编程技巧,也就 ...

  9. [vue] 你知道vue中key的原理吗?说说你对它的理解

    [vue] 你知道vue中key的原理吗?说说你对它的理解 key的作用主要是为了高效的更新虚拟DOM; 如果没有唯一的key, 数据更新时, 相同节点更新前后无法准确一一对应起来,会导致更新效率降低 ...

  10. Vue学习笔记--Vue双向绑定实现原理

    我们知道Vue可以实现数据双向绑定,Angular和Vue都是采用的MVVM 模式,意思就是当M(模型层)层数据进行修改时,VM层会监测到变化,并且通知V(视图层)层进行相应的修改,反之修改V层则会通 ...

最新文章

  1. 一本书——《锋利的jQuery》
  2. Ubuntu系统如何安装软件
  3. 工信部IC power大讲堂(南京)开班,特邀国际名家做核心技术分享
  4. ALHLS:Apple低延迟HLS技术
  5. Hive 01_初学必知
  6. leetcode455. 分发饼干(贪心算法)
  7. 对内存重叠的深入认识
  8. OpenCV-数组加权和cv::addWeighted
  9. Java创建线程的三种方法
  10. 远程打开其他电脑的computer management
  11. vue对象属性为null_如何避免在Vue中使用null作为class的空值
  12. ES6 json转map map转json
  13. Windows如何安装Clouda
  14. angular bugger
  15. 【开发者必看】APP《安全评估报告》填写范例
  16. 分布式数据库 Tracing (一)— Opentracing
  17. 数据分析-思维分析逻辑day02
  18. C语言,练习8.9 n*n阶矩阵对角线元素之和
  19. windows主机中的文件无法拖拽到虚拟机的Ubuntu系统中(即使安装了vmtools)
  20. 忆旧路:雄关漫道真如铁,而今迈步从头越

热门文章

  1. 都市美信男 Metrotextual
  2. java通讯框架_gim: 一个简单易用,稳定高效的及时通讯框架(java、android)
  3. 怎么解开payload.bin
  4. 让你的app体验更丝滑的11种方法!冲击手机应用榜单Top3指日可待
  5. centos7基本使用教程
  6. 如何从Apple App Store获得退款
  7. 用Python解小学数学题(人教版一年级(下)第45页:猜数字)
  8. mysql最大公约数函数_求最大公约数和最小公倍(PHP)
  9. 我的世界服务器怎么修改皮肤,我的世界怎么换皮肤 我的世界皮肤更换使用教程...
  10. storm显微镜成像原理_延展显微镜成像技术及其应用