20_Vue如何监测数组类型数据发生改变的?
通过上一节,我们知道了vue检测对象数据发生改变的原理
但是还有个api我们没有讲解,Vue.set();
这个API比较适合在理解了对象检测的原理后进行讲解
案例准备
html
<!-- 创建一个容器 -->
<div class="app">
<h1>姓名:{{student.name}}</h1>
<h1>年龄:{{student.age}}</h1><br>
<h2>朋友们</h2>
<ul>
<!-- 列表渲染 == friends -->
<li v-for="(item,index) in friends">
{{item.name}}-{{item.rage}}-{{item.mage}}
</li>
</ul>
</div>
data配置项
<script>
const vm = new Vue({
el: '.app',
data: {
student: {
name: 'wavesbright',
age: 21,
},
friends: [ // 真实年龄,内心年龄
{name: "Jack",rage: 32,mage: 40},
{name: "Jony",rage: 24,mage: 45},
{name: "Jone",rage: 28,mage: 50},
]
},
methods: {
},
});
</script>
页面效果

需求
- 我的数据都是写在data当中的,通过vue的数据代理
- 在页面当中实现了响应式开发
- 那么现在有一个问题
- 我想给,student 添加一个属性,这个属性是后来添加的,不是之前就添加的
- 想让 这个属性能够实现响应式,应该如何实现?
错误示范
- 直接在vm后面加个属性不就完了?
- 修改 _data,然后给它添加一个属性?
- 上述两个操作的问题,添加的属性没有进行数据代理
- 无法完成响应式
- 仔细看的话,在student这个对象当中,sex这个属性是没有get和set函数的
添加测试

我们在这里添加一个渲染项,然后我们添加属性试试,现在我data当中是没有这个属性的

并不能被vue所识别到
那么我们后面想要自己添加属性就没有办法完成响应式了吗,诶,这就是我们接下来要引入的API
Vue.set()
- 该API需要三个参数
- target: 目标
- key: 添加的属性名
- val: 添加的属性值

我现在算是明白了,小程序的 this.setData() 就是从这里变来的
这里其实应该是 .student的;因为操作的都是同一个对象的地址
set的局限性

我现在要在data当中,添加一个属性,这个属性是leader == 校长
我们使用.set添加试试

- 这里报错的意思就是,不允许直接在vue实例身上添加一个属性
- 解读一下这段话哈
- 我现在是在_data当中添加属性
- 但是这个添加的属性,最后会挂载在vue实例身上
- 所以,这里使用.set是不允许的,不能直接添加
- .set()不能在data当中直接添加属性
- 只能给data当中的某个对象(student)添加属性
vm是不能作为target的,vm当中的data,也不能作为target

监测数组
准备工作

- 新建一个demo,重新配置了数据项data
- 在data当中有两个属性,一个numbers的数组,一个student的对象
- 我们查看vue实例对象,在查看之前可以很明确的说,numbers 和 student 都挂载在了vue实例身上,并且,有专门为他俩服务的get和set

数据代理

现在我们点击去看看二者有什么不同,或者说,vue当中对数组和对象类型的数据是如何代理的
数组和对象的不同
数组

对象

区别,目前而言
- 数组当中的数据,是没有进行数据代理的,没有专门为 元素 服务 的 get和set
- 而对象当中,每个属性都是有get和set的,哪怕这个属性是对象也有
- 也就是说,如果我们直接在vue当中直接修改numbers对应索引的值,vue是观测不到的
直接修改numbers
我们写一串DOM元素进行测试
<div class="app">
<ul>
<li v-for="item in numbers">{{item}}</li>
</ul>
</div>

现在,我直接在控制台中对数组当中的元素进行修改
我们将最后一项 从5改为6

数据的确修改成功了,但是vue检测不到,页面无法响应
之前的错误解释
现在,我们来回顾一下之前遇到的bug,我们添加一个persons对象数组

从控制台我们来观察一下这个persons

- 这是一个对象数组,这个数组当中的每一项数据,都没有被进行数据代理
- 但是因为每一项 数据 都是对象类型,所以 在对象类型当中 数据是进行了代理(get和set)的
- 这里很重要,请仔细看

所以为什么下面的修改不起作用,因为根本没代理,没有代理无法完成响应式数据
这个问题解决了顺势抛出下一个问题,vue怎么就知道数组内部的属性发生改变了呢,它是如何监测到的?
vue如何监测?

- 蓝色框当中的都是可以对数组进行修改的,会改变原有数组结构
- 但是filter不会,他会返回一个新数组,不修改原数组
- arr 调用了蓝色框框当中的数组API,自身才会发生改变
- vue当中规定,你只有使用了上述的7个方法,我才承认你修改数组了
那它咋知道我调用了上面的7个API呢?
包装技术
原形
使用 Array这个原形对象身上的 push 举例子
这个push,是给数组调用的

我们在控制台上来个数组

这个push是哪里来的?==> 其实是一层一层嵌套的,从原形对象身上来的

二者身上的push是相等的

vue
vue身上的数组,使用的并不是 原形数组Array身上的 API函数
如何测试?
很简单,回到我们刚刚的案例

这下您能明白了吗
流程
当你对一个被vue所管理的数组进行了api的调用(push,shift,unshift.....)

你调用的这个API,就不是原型对象Array身上的API了;而是vue的api
在这个api当中,会做两个步骤
- 调用原形身上的API(push.....)
- 重新解析模板,生成虚拟dom.......那一套流程
是这么一回事吗,我们看下官网是如何解答的
官网寻找答案
- 点击 列表渲染
- 点击 数组更新检测

我们来看这句话

enmmmm,后面没讲了,基本其实到这里就差不多了,后面的都需要在实际开发当中去慢慢琢磨了
尚硅谷yyds,黑马也是
你们都是我的天使
20_Vue如何监测数组类型数据发生改变的?的更多相关文章
- 19_Vue如何监测到对象类型数据发生改变的?
数据更新 关于监视 我们之前讲过,我们在data当中配置的属性,最终会挂载在vue实例身上,而data这个配置项,最终也会在vue身上成为一个新的属性 == _data 当我们在页面DOM当中,去使用 ...
- spring boot 传输数组类型数据
需要在参数加上@RequestBody注解 参考资料:https://blog.csdn.net/u012129558/article/details/51768985
- mybatis 处理数组类型及使用Json格式保存数据 JsonTypeHandler and ArrayTypeHandler
mybatis 比 ibatis 改进了很多,特别是支持了注解,支持了plugin inteceptor,也给开发者带来了更多的灵活性,相比其他ORM,我还是挺喜欢mybatis的. 闲言碎语不要讲, ...
- 关于Delphi中二维数组的声明和大小调整(对非基本类型数据,小心内存泄漏)
这是一个实例: procedure TMainForm.Button1Click(Sender: TObject);var arr:array of array of string;begin s ...
- 字符类型char、字符串与字符数组、字符数组与数据数组区别
字符类型是以ASCII码值运算的:小写字母比相应的大写字母大32,其中A=65,a=97 Esc键 27(十进制).'\x1B'(十六进制).'\33'(八进制) 转义字符:\0 空字符 AS ...
- js 对 只包含简单类型数据的对象 为元素 组成的数组 进行去重
/** * 对于由简单类型数据组成的对象为元素组成的数组进行去重操作 * @params {Array} 需要去重的对象数组 * @returns {Array} 去重后的对象数组 */ functi ...
- EF里Guid类型数据的自增长、时间戳和复杂类型的用法
通过前两章Lodging和Destination类的演示,大家肯定基本了解Code First是怎么玩的了,本章继续演示一些很实用的东西.文章的开头提示下:提供的demo为了后面演示效果,前面代码有些 ...
- EF——Guid类型数据的自增长、时间戳和复杂类型的用法 03 (转)
EF里Guid类型数据的自增长.时间戳和复杂类型的用法 通过前两章Lodging和Destination类的演示,大家肯定基本了解Code First是怎么玩的了,本章继续演示一些很实用的东西.文 ...
- matlab结构体、数组和单元数组类型的创建
matlab结构体.数组和单元数组类型的创建 @ 目录 matlab结构体.数组和单元数组类型的创建 matlab结构体类型 数组类型 单元数组类型 matlab结构体类型 通过字段赋值创建结构体 创 ...
随机推荐
- 定制化JDK升级引发的离奇事件
1.背景 由于Oracle对外宣称Oracle JDK停止免费用于商用.公司法务部门评估之后担心后续会惹上光司,于是就开始了JDK升级-将所有服务Oracle修改为OpenJDK.上周开始微服务JDK ...
- 【java】学习路径32-绝对路径与相对路径
获取文件路径的时候,我们发现有两个方法,getAbsolutePath和getPath两个方法. 前者是获取绝对路径,后者是相对路径. 绝对路径指的是完整路径,从盘符开始. 相对路径指的是从java当 ...
- Android平台摄像头/屏幕/外部数据采集及RTMP推送接口设计描述
好多开发者提到,为什么大牛直播SDK的Android平台RTMP推送接口怎么这么多?不像一些开源或者商业RTMP推送一样,就几个接口,简单明了. 不解释,以Android平台RTMP推送模块常用接口, ...
- zabbix_agentd断断续续端无法访问问题记录
问题现象: zabbix监控上出现zabbix_agentd无法访问,但是实际上zabbix_agentd是存活状态 每隔一段时间就会出现这样的情况 问题原因 zabbix_agentd端任务较多,活 ...
- 【读书笔记】C#高级编程 第一章 .NET体系结构
(一) C#与.NET的关系 1) C#编写的所有代码都使用.NET Framework运行. 2) C#是一种编程语言,.NET Framework是一个平台(可开发.部署和执行分布式应用程序). ...
- 读完 RocketMQ 源码,我学会了如何优雅的创建线程
RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时.高可靠的消息发布与订阅服务. 这篇文章,笔者整理了 RocketMQ 源码中创建线程的几点技巧,希望大家读完之后,能 ...
- 《Java笔记——基础知识点》
Java笔记--基础知识点 位运算符操作的都是整型的数据. 位运算符是直接对整数的二进制进行计算. 整数不能进行逻辑运算. 运算符优先级别由高到低分别是:() > ! > 算术 ...
- MQ的消息丢失/重复/积压的问题解决
在我们实际的开发过程中,我们肯定会用到MQ中间件,常见的MQ中间件有kafka,RabbitMQ,RocketMQ.在使用的过程中,我们必须要考虑这样一个问题,在使用MQ的时候,我们怎么确保消息100 ...
- 7、System类
System类 常见方法 exit 退出当前程序 System.out.println("ok1"); //1. exit(0) 表示程序退出 //2. 0 表示一个状态,正常的状 ...
- JS 模块化 - 03 AMD 规范与 Require JS
1 AMD 规范介绍 AMD 规范,全称 Asynchronous Module Definition,异步模块定义,模块之间的依赖可以被异步加载. AMD 规范由 Common JS 规范演进而来, ...




