Vue对象的深层劫持详细讲解
作者:BraveWangDev 发布时间:2024-04-26 17:40:20
一,前言
上篇,主要介绍了在 Vue 的数据初始化流程中,对象属性的单层劫持是如何实现的
回顾一下,主要涉及以下几个核心点:
data 为函数和对象的处理,及当 data 为函数时的 this 指向问题
Observer 类:对数据进行观测
walk 方法:遍历 data 属性(对象属性遍历)
defineReactive 方法:利用 Object.defineProperty 实现数据劫持
本篇,继续对 data 数据进行初始化操作,对象属性的深层劫持
二,对象属性的深层观测问题
1,抛出问题
当前版本的代码逻辑:
如果,data 对象中的属性,还是一个对象(称为obj)
那么,这个对象(obj)中的属性是不会被观测的(目前所说的观测还仅仅停留在数据劫持阶段)
就是说,当前仅实现了对 data 对象中属性的单层劫持,嵌套对象不会被深层劫持
2,测试问题
<script>
let vm = new Vue({
el: '#app',
data() {
// data函数返回的对象中,obj属性为一个对象,它的属性不会被观测
return { message: 'Hello Vue', obj: { key: "val" } }
}
});
</script>
3,查看结果
new Vue 时,传如的 options 选项中的 data 函数,
data 函数中,属性 obj 的值依然是一个对象 { key: “val” }
对象 { key: “val” } 中的 key,此时没有被添加 get 和 set 方法,说明 key 没有被劫持
三,对象属性深层观测的实现
1,实现思路
TODO:需要先回顾一下,对象属性单层观测的流程
有了 data 对象单层观测的经验,对象属性 obj 深层劫持就简单多了
当对象属性 obj 即将被 Object.defineProperty 劫持时,
再对 obj 对象做一次“对象的单层劫持”
更深层的对象属性劫持,就是在递归执行“对象的单层劫持”
即:当属性为对象类型时(非 null)
继续进行 observe 观测,observe 的递归就实现了对象属性的深层劫持
2,代码逻辑
function defineReactive(obj, key, value) {
observe(value);// 递归实现深层观测
Object.defineProperty(obj, key, {
get() {
return value;
},
set(newValue) {
if (newValue === value) return
value = newValue;
}
})
}
TODO:需要突出递归的逻辑
四,data 相关优化
TODO:结合对象属性观测的特点,介绍 data 的相关优化
五,结尾
本篇主要实现了 Vue 数据初始化流程中,对象属性的深层劫持,核心思路就是递归;
通过data = isFunction(data) ? data.call(vm) : data;处理后的data一定是对象类型
通过data = observe(data)处理后的 data 就实现了数据的响应式(目前只有劫持)
observe 方法最终返回一个 Observer 类
Observer类初始化时,通过 walk 遍历属性
对每一个属性进行 defineReactive(Object.defineProperty)就实现对象属性的单层数据劫持
在 defineReactive 中,如果属性值为对象类型就继续调用 observe 对当前的对象属性进行观测(即递归步骤 3~5),这样就实现了对象属性的深层数据劫持
下一篇,数组的劫持
来源:https://blog.csdn.net/ABAP_Brave/article/details/128566839


猜你喜欢
- Python3安装后SSL问题问题编译安装时已经指定了–with-openssl的参数并且指向了你的openssl的源码
- 一、单循环动态设置ref1.设置:【:ref=“‘XXX’ + index&am
- 在python中利用numpy创建一个array, 然后我们想获取array的最大值,最小值。可以使用一下方法:一、创建数组这样就可以获得一
- 本文实例为大家分享了python实现图片识别汽车的具体代码,供大家参考,具体内容如下准备工作1、登陆开发者控制台2、安装 pip insta
- 适合的读者:有经验的开发员,专业前端人员。 原作者: Dmitry A. Soshnikov 发布时间: 2010-09-02 原文:htt
- <html> <body> &nbs
- 引言除非您正在对服务进行原型设计,否则您可能会关心应用程序的内存使用情况。内存占用更小,基础设施成本降低,扩展变得更容易/延迟。尽管 Go
- 目标学习读取视频,显示视频和保存视频。学习从相机捕捉并显示它。你将学习以下功能:cv.VideoCapture(),cv.VideoWrit
- 1.先停止mysqld.exe的进程2.打开cmd进入到你mysql的bin目录下输入此命令:mysqld --skip-grant-tab
- 前言最近由于项目需要,需要读取一个含有中文的txt文档,完了还要保存文件。文档之前是由base64编码,导致所有汉字读取显示乱码。项目组把b
- 算法是计算机科学中一个重要的研究方向,是解决复杂问题的关键。在计算机世界中,算法无处不在。数据库是存储数据和执行大批量计算的场所,在数据库中
- 本文为大家分享了MySQL 8.0.29 安装配置方法图文教程,供大家参考,具体内容如下一、下载MySQL1、进入MySQL官网MySQL并
- 大家都知道一些论坛的标题有高亮显示功能,在这里我不讨论也不研究论坛普遍的实现方法,下面是我的实现方法:实现思路:把要高亮显示的标题加上特定标
- 话不多说,请看代码:function removeRepeat(data) {var temp = "";var mai
- 今天在测试以下代码时遇到该错误:session_start();$_SESSION['username']=$usernam
- 之前只是单纯的会用,因为vue关于父子组件通讯差别有一点点大。1.在父组件内传递变量的时候,需要加冒号:,否则你就只是单纯的传递了一个字符串
- 一、垃圾还是经典网页技术更新很快,一个网站的界面设计寿命仅仅2-3年而已。不管是垃圾还是精品,都没有所谓的经典。经典只存在于是哪个首次成功创
- 二维矩阵的transpose函数:不晓得该怎么起头,直接上干货。transpose()简单来说,就相当于数学中的转置,在矩阵中,转置就是把行
- 由 于数据库日志增长被设置为“无限制”,所以时间一长日志文件必然会很大,一个400G的数据库居然有600G的LOG文件,严重占用了磁盘空间。
- 常见的SQL问题:◆选择重复,消除重复和选择出序列有例表:empemp_no name age001 Tom 17002 Sun 14003