【学习笔记】Vue3源码解析:第二部分-实现响应式(2)

课程地址:【已完结】全网最详细Vue3源码解析!(一行行带你手写Vue3源码)

第二部分-实现响应式(2):(对应课程的第6-9节)

第6节:《实现proxy代理以及解决重复代理的问题》

1、在入口文件中暴露4个响应式API接口:

在这里插入图片描述

2、既然是从当前文件夹下的reactive中引入的这4个接口并暴露,那么接下来在当前文件夹下新建reactive.ts,并在其中编写代码:
定义并暴露了这4个方法,这4个方法都接收一个target入参,然后在函数内部又返回了一个createReactiveObj函数,此函数是实现响应式的核心方法,它接收三个参数:target(传入的参数)、isReadonly(是否只读)、baseHanlers(实现响应式的配置对象)
在这里插入图片描述

3、接下来编写createReactiveObj函数,这个方法是实现响应式的核心方法,首先需要判断数据是否对象类型,先在shared文件夹下定义一个公共方法 isObject:

在这里插入图片描述

4、由于在shared里面添加了公共方法,需要运行npm run build 进行打包才能将shared下的代码也进行打包(因为我们前面配置的npm run dev 只会对reactivity下的内容进行打包):

5、打包完成之后会发现packages/shared下已经出现了打包生成的文件,其中已经有了我们刚刚写的isObject方法:

在这里插入图片描述

6、打包之后运行一下 yarn install,重新安装一下,然后会发现 node_modules/@vue/shared 下会出现刚刚打包的 isObject 相关代码:

在这里插入图片描述

在这里插入图片描述

小总结:在shared里新增公共方法后,需要运行 npm run build 进行打包,将代码打包到packages下,然后需要运行 yarn install 重新安装,将代码同步到node_modules/@vue/shared下,之后才可以引用其中的方法。

7、引入isObject公共方法:

在这里插入图片描述

8、处理一个问题:假如一个已经被reactive处理过的数据,再次传递给了reactive,此时需要判断一下,如果这已经是一个被reactive处理过的数据,则直接返回处理后的数据,无需再次重复处理。实现方式为:用一个 weakMap 数据结构将reactive处理过的数据记录下来,在处理之前,先来判断一下这个存储被处理过的数据的结构中是否有这个数据,有则直接返回,无则进行处理并记录到weakMap数据集中。

在这里插入图片描述
在这里插入图片描述

第7节:《实现代理proxy中的get》

1、将4个响应式API对应的hander移动到一个单独的文件 baseHandlers.ts 中,并在reactive.ts中导入和使用:
在这里插入图片描述

2、在 baseHandlers.ts文件中定义并导出这4个handlers对象,由于4个handler都会包含一个get方法和一个set方法,所以仍然采用柯里化的形式,用一个createGetter函数,来统一处理相同的逻辑,通过传入不同的参数控制不同的逻辑:

在这里插入图片描述

3、编写createGetter公共方法:这个方法返回一个get函数,其参数为target(传递给4个响应式API的需要处理的对象数据)、key(读取的对象属性)以及receiver。在这个函数中,首先通过Reflect取到目标对象的属性值,然后根据不同参数进行判断:如果不是只读,那么通过effect进行收集依赖,相当于vue2中的watcher;如果是浅的,则直接返回属性值,因为Proxy默认只会对目标对象的第一层实现代理,并不会自动去处理嵌套的更深层级。最后将属性值返回,代码如下:

在这里插入图片描述

补充:Proxy的handler对象中get函数接收到的第三个参数receiver,经测试就是生成的Proxy对象:

在这里插入图片描述

在这里插入图片描述

4、通过Proxy对对象实现代理,默认只会对对象第一层进行代理;对比vue2,初始时如果遇到对象属性值又是对象,则会跑递归,给所有嵌套属性都实现watcher,即数据的“监听”

在这里插入图片描述

5、处理对象的属性值又是一个对象的情况:判断其属性值是对象类型,则递归调用响应式方法,如果是只读的,则继续调用readonly;如果不是只读,则继续调用reactive。

在这里插入图片描述

注意:这里的面试点:懒代理。这里不像vue2初始时就直接遍历跑递归,将对象的所有嵌套属性全部层层递归实现watcher,vue3的这种处理方式称为“懒代理”,只在用到了这个属性时(模板读取这个属性值时),才会去判断该属性值是否对象,如是才会去将该属性值对应的对象处理为Proxy响应式对象;如果没有用到这个属性,则不会去实现这个属性值对应的对象的响应式处理。这样的处理方式大大提高了性能。
vue3相对vue2实现响应式有什么不同,对性能提升有什么帮助?首先,vue3通过proxy实现对目标对象的代理,从而实现响应式。在通过proxy对目标对象代理的过程中,默认只会对对象第一层数据进行代理,如果不会读取或使用嵌套的对象属性值,则不会对嵌套的对象属性值进行代理,只有当使用嵌套的对象属性值时,才会对其进行代理。这样的处理方式大大提高了性能。

第8节:《实现响应式》

1、实现Proxy的handler中的set方法:
由于reodonly与shallowReadonly不能设置值(视频课程里应该是没考虑shallowReadonly的浅层次只读),所以在这两个方法对应的handler中的set方法里,直接打印一个提示信息:设置值失败
在这里插入图片描述

2、在packages文件夹下新建examples,新建1.reactive.html文件,引入打包后的reactivity文件,测试刚刚实现的reactive方法:

在这里插入图片描述

在这里插入图片描述

测试readonly方法:
在这里插入图片描述

在这里插入图片描述
测试 shallowReactive :

在这里插入图片描述

在这里插入图片描述

3、实现 reactive 与 shallowReactive 中Proxy对象handler中的set方法编写,统一用一个createSetter方法来处理:

在这里插入图片描述
在这里插入图片描述

第9节:《回顾上节课的知识点》

完善笔记:
在这里插入图片描述

在这里插入图片描述

优化代码,对象合拼:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2812082.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

GDB之(1)入门指令参数介绍

GDB之(1)基础入门指令参数介绍 Author:Once Day Date: 2022年7月29日/2024年2月26日 漫漫长路,才刚刚开始… 全系列文章请查看专栏: Linux实践记录_Once-Day的博客-CSDN博客 推荐参考文档: GDB: The GNU Project Debugger (sourceware.o…

32单片机基础:TIM定时中断

STM32中功能最强大,结构最复杂的一个外设——定时器 因为定时器的内容很多,所以本大节总共分为4个部分,8小节。 第一部分:主要讲定时器基本的定时功能,也就是定一个时间,然后让定时器每隔这个时间产生一个中断&#…

C++笔记之执行一个可执行文件时指定动态库所存放的文件夹lib的路径

C++笔记之执行一个可执行文件时指定动态库所存放的文件夹lib的路径 参考博文: 1.C++笔记之执行一个可执行文件时指定动态库所存放的文件夹lib的路径 2.Linux笔记之LD_LIBRARY_PATH详解 3.qt-C++笔记之使用QProcess去执行一个可执行文件时指定动态库所存放的文件夹lib的路径 c…

适合新手博主站长使用的免费响应式WordPress博客主题JianYue

这款JianYue主题之所以命名为 JianYue,意思就是简单而不简约的。是根据Blogs主题优化而成,剔除了一些不必要的功能及排版,仅保留一种博客布局,让新手站长能够快速手上WordPress。可以说这款主题比较适合新手博主站长使用&#xff…

GDB动态调试学习-2-【断点 观察点】

文章目录 在程序地址上打断点在程序入口处打断点获取程序入口地址 在命名空间设置断点命名空间给命名空间的函数下断电 在文件行号上打断点保存已经设置的断点设置临时断点设置条件断点忽略断点 在程序地址上打断点 当调试汇编程序,或者没有调试信息的程序时&#…

【Rust】简介、安装和编译

文章目录 一、Rust简介二、Rust 安装三、Rust 程序结构3.1 模块(Modules):3.2 函数(Functions):3.3 变量(Variables):3.4 控制流(Control Flow)&a…

Verilog中向量的位截取、拼接

1、位截取: 当索引均为常数 例如:men[4:1]men[4-:4] men[1:4] 索引是变量 语法为:men[base:width] or men[base-:width] 例如:if cnt8, men[cnt:4] 等于 men[11:8]; men[cnt-:4] 等于men[8:5]. 其中,base可变&am…

el-table样式问题:如何修改element-ui表格中按钮悬浮显示但是被el-table溢出隐藏的问题?

最近在写elment-ui样式表格中遇到了溢出隐藏的问题 修改前 修改后 是由于el-table__body-wrapper为 overflow:hidden导致的 解决方式: .el-table__body-wrapper {overflow: visible !important; } //或者 /deep/.el-table__body-wrapper {overflow: v…

ONLYOFFICE 桌面编辑器 v8.0 更新内容详细攻略

文章目录 引言PDF 表单RTL 支持电子表格中的新增功能Moodle 集成用密码保护 PDF 文件从“开始”菜单快速创建文档本地界面主题下载安装桌面编辑工具总结 引言 官网链接: ONLYOFFICE 官方网址 ONLYOFFICE 桌面编辑器是一款免费的文档处理软件,适用于 Li…

主机字节序与网络字节序

大端序和小端序 大端序(Big Endian)和小端序(Little Endian)是两种计算机存储数据的方式。 大端序指的是将数据的高位字节存储在内存的低地址处,而将低位字节存储在内存的高地址处。这类似于我们阅读多位数时从左往右…

【电子书】研发管理

资料 wx:1945423050 整理了一些互联网电子书,推荐给大家 研发管理 ABAQUS 6.14中文版有限元分析与实例详解.epubAkka入门与实践.epubAltium Designer 16电路设计与仿真从入门到精通.epubAltium Designer17电子设计速成实战宝典.epubApache Kafka源码剖…

ChatGPT带火的HBM是什么?

“ChatGPT是人工智能领域的iPhone时刻,也是计算领域有史以来最伟大的技术之一。” 英伟达创始人兼CEO黄仁勋此前这样盛赞ChatGPT。 ChatGPT突然爆火,对大算力芯片提出了更高更多的要求。近日,据韩国经济日报报道,受惠于ChatGPT&am…

ZYNQ:串口-CAN协议转换

前言 目前已经实现zynq的PS-CAN和PL-CAN功能。串口-CAN协议转换是实现以太网-CAN功能的过渡,通过这个流程能够减少后期以太网工程出现问题的频率。阶段性功能目标如下: 实现数据在CAN调试助手和串口调试助手之间的来回转换,从而了解中断机制…

CMU15445实验总结(Spring 2023)

CMU15445实验总结(Spring 2023) 背景 菜鸟博主是2024届毕业生,学历背景太差,导致23年秋招无果,准备奋战春招。此前有读过LevelDB源码的经历,对数据库的了解也仅限于LevelDB。奔着”有对比才能学的深“的理念,以及缓解…

MySQL基础(二)

文章目录 MySQL基础(二)1. 数据库操作-DQL1.1 介绍1.2 语法1.3 基本查询1.4 条件查询1.5 聚合函数1.6 分组查询1.7 排序查询1.8 分页查询1.9 案例1.9.1 案例一1.9.2 案例二 2. 多表设计2.1 一对多2.1.1 表设计2.1.2 外键约束 2.2 一对一2.3 多对多2.4 案…

AI算法核心概念与方法汇总

一、AI模块简介(45个) 以下是提升AI大模型能力时涉及的核心概念与方法: 1. **迁移学习(Transfer Learning)**: - 利用在源领域预先训练好的模型,在目标领域上进行微调,从而利用已有…

【深度学习】Pytorch教程(十三):PyTorch数据结构:5、张量的梯度计算:变量(Variable)、自动微分、计算图及其可视化

文章目录 一、前言二、实验环境三、PyTorch数据结构1、Tensor(张量)1. 维度(Dimensions)2. 数据类型(Data Types)3. GPU加速(GPU Acceleration) 2、张量的数学运算1. 向量运算2. 矩阵…

七大查找算法详解并附代码实现

基本查找 也叫做顺序查找 说明:顺序查找适合于存储结构为数组或者链表。 基本思想:顺序查找也称为线形查找,属于无序查找算法。从数据结构线的一端开始,顺序扫描,依次将遍历到的结点与要查找的值相比较,…

景联文科技:引领战场数据标注服务,赋能态势感知升级

自21世纪初,信息化战争使战场环境变得更为复杂和难以预测,持续涌入的海量、多样化、多来源和高维度数据,加大了指挥员的认知负担,使其需要具备更强的数据处理能力。 同时,计算机技术和人工智能技术的飞速发展&#xff…

计算机操作系统(慕课版)第一章学习笔记

第一章学习笔记 1.1 操作系统的概念 操作系统是配置在计算机硬件上的第一层软件,是对硬件系统的首次扩充,其主要作用是管理硬件设备,提高他们的利用率和系统吞吐量,并为用户和应用程序提供一个简单的接口,以便用户和应…