【Vue2.x 源码学习】第八篇 - 数组的深层劫持
一,前言
上篇,通过 Vue Demo 的断点调试,对当前版本数据劫持、数据代理进行了简单的流程梳理
同时,对照 Vue2.x 提供的功能,分析了当前版本数据观测的问题和不足
本篇,数组的深层观测
二,数组深层劫持的思路
1,问题分析
当前代码版本中,遇到数据类型时,会对当前数组进行原型方法的重写,实现数组的数据劫持
但是,当前代码仅对数组 7 个方法进行劫持,尚未实现劫持后的逻辑
对于数组类型中嵌套的内容(数组、对象、普通值)还并没有进行深层处理
所以,尚不支持对于数组中的内容(对象、数组、普通值)进行观测
即,以上代码片段,对数组中的数组添加内容,是不会被重写后原型方法所劫持的
2,解决方案
对数组的数据劫持操作进行递归处理,实现嵌套数组的数据劫持能力
3,性能问题
Vue2.x 中,由于需要对数组的原型方法进行递归重写,
因此,当数组层次过深时,就容易产生性能问题;(需重写属性、方法和数组的链)
三,数组深层劫持的实现
1,代码实现
通过以上分析,实现数组的深层劫持,需要处理两种情况:
数组中嵌套数组
数组中嵌套对象
observeArray 方法:为数组中的每一项,调用 observe 进行深层观测处理
这样,数组中的数组 [ [] ]、数组中的对象 [ {} ] ,两种情况都实现了数据的深层观测
2,问题分析
由于仅重写了数组的部分原型方法,未对每一项进行数据劫持
所以,数组中的普通值,不能被观测;(仅重写数组方法,递归中对值类型不再处理)
数组中的引用类型,能够被观测;(observe 实现对象类型深层观测)
举例分析:
若 vm.arr[0] 为普通值:(仅重写数组方法,递归中对值类型不再处理)
vm.arr[0] = 100 操作数组索引,不会触发视图更新(没对数组索引观测)
若 vm.arr[0] 为对象:(observe 实现对象类型深层观测)
vm.arr[0].a = 1 修改对象属性,会触发视图更新
四,结尾
又成功水了一篇,还剩 13 篇
本篇,介绍了数组的深层观测实现,核心几个点如下:
之前对数组类型的处理中,仅对当前数组进行了部分原型方法重写操作,即仅实现了数组的单层数据劫持能力,
继续对数组进行 observe 递归观测操作;实现数组中嵌套结构的劫持,即数组嵌套数组、数组嵌套对象
注意:observe 方法对非对象不进行操作,所以数组中的值类型是不会被劫持的
目前,数据观测剩余问题:
实现对象中新增对象的观测(深层)
实现对象中新增属性的观测
实现数组中新增对象的观测(深层)-原型方法重写
下一篇,对象中新增对象的深层观测
评论