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
猜你喜欢
- 前言本文提供在在无音频的视频中添加音频的python工具,附上代码。环境依赖ffmpeg环境安装,可以参考:windows ffmpeg安装
- 事件调度sched 模块内容很简单,只定义了一个类。它用来最为一个通用的事件调度模块。class sched.scheduler(timef
- tkinter下载进度条利用python爬取网站数据进行下载时,显示下载进度# 设置下载进度条tk.Label(window, text=&
- #常用的几个代码--查询临时表空间select name from v$tempfile;--查询表空间select name from v
- 经常遇到百度网盘的压缩文件加密了,今天我们就破解它!实现思路上篇文章给大家介绍了爆破密码的思路,感兴趣的朋友可以了解下。其实都大同小异:无非
- 本文实例讲述了python类和对象用法。分享给大家供大家参考,具体如下:前面我们都是用python面向过程编程,现在来用python创建类和
- 阅读上一篇:一个完美网站的101项指标.第六部分.性能 符合 W3C 标准是网站的发展趋势,目前,几乎所有的浏览器都使用 W3C 标准,W3
- 本文实例讲述了python实现爬取百度图片的方法。分享给大家供大家参考,具体如下:import jsonimport itertoolsim
- 从容器、可迭代对象谈起所有的容器都是可迭代的(iterable),迭代器提供了一个next方法。iter()返回一个迭代器,通过next()
- 第一种,在方法后面加问号,然后执行,如 abs?第二种,光标移动到方法上面,按shift+tab,弹出文档,连续按选择文档详细程度补充知识:
- 作为一个.net后台开发的程序猿,博客里既然大多都是前端相关的博文。是不是该考虑换方向了,转前端开发得了 ...小小吐槽一下,近期受该不该跳
- 实现一个优先级队列,每次pop的元素要是优先级高的元素,由于heapq.heapify(list)默认构建一个小顶堆,因此要将priorit
- 关于一些代码里的解释,可以看我上一篇发布的文章,里面有很详细的介绍!!!可以依次把下面的代码段合在一起运行,也可以通过jupyter not
- 如下所示:file->settings->Editor->General->Console里面的console co
- 1.MySQL中并发和隔离控制机制Meta-data元数据锁:在table cache缓存里实现的,为DDL(Data Definition
- 一、修改表格数据类型 DataFrame 列的顺序实战场景:Pandas 如何修改表格数据类型 DataFrame 列的顺序1.1
- © 版权符号显示不清楚,就是那个圈C,在某些网站上就是显示太小,看不清楚。一开始还以为是字体大小的原因,调大以后,还是一样
- SQL Server 2000 的 XML 功能可以简化将现有代码作为 Web 服务提供的任务。本文集中讨论了传入和传出 Transact
- 方式一:直接通过数据库厂商提供的相关驱动步骤导入相关驱动(Build Path)创建Driver类的实例化对象获取要连接数据库的URL创建P
- 前言:python利用matplotlib库中的plt.ion()函数实现即时数据动态显示:1.非定长的时间轴代码示例:# -*- codi