【Vue2.x 源码学习】第九篇 - 对象数据变化的观测情况
一,前言
上篇,主要介绍了数组深层观测的实现,核心几个点如下:
最初仅对数组类型进行了原型方法重写,并未进行递归处理,所以,当时仅实现了数组的单层劫持;
通过对数组进行 observe 递归观测,实现了对数组嵌套结构的劫持(数组中嵌套数组、数组中嵌套对象)
但是,由于 observe 方法对非对象类型不进行处理,所以,数组中的值类型将不会被劫持;
与 Vue2.x 功能进行对比,目前代码仍需实现以下功能:
对象中,老属性变更为对象、数组的情况 - 需对修改值进行深层观测处理
对象中,新增属性的情况 - 需进行说明
数组中,新增对象、数组、普通值的情况 - 需实现数组的方法重写并对修改值进行递归处理
综上,将其划分为两大部分:
对象数据变化:对象中,老属性变更为对象;对象中,新增属性的情况;
数组数据变化:对象中,老属性变更为数组;数组中,新增对象、数组、普通值的情况;
本篇,对象数据变化的观测情况(老属性变更为对象、新增属性的情况)
由于数组的递归劫持尚未实现,故本篇不包含对象老属性变更为数组的情况;
将“对象老属性变更为数组”和“数组数据变化的观测情况”进行合并;
20210610:TODO-思考了一下,“对象中,老属性变更为数组的情况”应该被放到本篇“对象数据变化的观测情况”一起,理由是:即便此时还没有为对象属性修改为数组做递归观测,也应该被归类为“对象数据变化”,且后续“数组数据”实现递归观测后,这个问题也会一并得到解决;
二,对象中,老属性变更为对象的观测问题
1,vm.message = { a: 100 }
将 data 中 message 属性由初始值"Hello Vue",变更为对象类型 { a : 100 }
由于 { a : 100 } 是 data 初始化完成后的新增对象,属于对象中新增对象
而当前版本中的新增对象不会被劫持,也就不会触发视图的更新
2,vm.message.a = 200
由于对象 { a : 100 } 没有被观测,所以修改此对象中的属性时,不会触发视图的更新
三,对象中,老属性变更为对象的观测实现
为了实现新增对象的数据观测,当设置的值为对象时,将此对象继续进行深层观测即可;
输出结果:
这样,就实现了对象中新增对象的深层观测
同时,对新增对象中的属性再次进行修改时,也能够通过数据劫持实现视图更新了
四,对象中,新增属性的情况
向 message 属性的新增对象 { a:100 } 中,添加一个不存在的属性 b,是否会进行数据劫持?
之前新增对象时,通过 observe 方法对新增对象进行了深层观测
而此时,向新增对象中添加新属性 b 并不会被劫持,也不会触发任何为其添加数据劫持的逻辑
所以,向新增对象中添加新属性将不会被劫持;
在 Vue2.x 中,为新增对象添加新属性,也是不能实现数据劫持的;
但可以通过 vm.$set 来实现对象中新增属性的数据观测能力;
五,结尾
又成功水了一篇,还剩 12 篇
本篇,主要介绍了数组数据变化的观测情况:
实现了对象老属性值变更为对象、数组时的深层观测处理;
结合实现原理,说明了对象新增属性不能被观测的原因,及如何实现数据观测;
下一篇,数组数据变化的观测情况(对象中,老属性变更为数组;数组中,新增对象、数组、普通值的情况;)
评论