Vue3 —— reactive 全家桶及源码学习

  • 该文章是在学习 小满vue3 课程的随堂记录
  • 示例均采用 <script setup>,且包含 typescript 的基础用法

前言

上一篇学习了 ref 全家桶,在此基础上一起学习下 reactive 全家桶

一、reactive 对比 ref

  • ref 可以接收 所有类型reactive 只能接收 object类型(array、object、Map、Set)
  • ref 在取值和赋值时都要通过 .valuereactive不需要
  • reactive 不能直接整体赋值,因为它是通过 proxy 创建的响应式对象,直接赋值会 破坏响应式
    • 解决方案 1:可以 调用一些原生操作,比如 数组可用 push、pop 等去修改
    • 解决方案 2:外面再包上一层

① 创建

import { reactive } from "vue";// object类型
const form = reactive({name: "xiaoman",age: 18,
});// array类型
const list = reactive<string[]>([]);

② 修改

// 错误。直接整体赋值会破坏响应式
// list = ["a", "b", "c"];// 可以通过原生方法去操作数据,不会破坏响应式
setTimeout(() => {const res = ["jay chou", "jolin"];list.push(...res);
}, 1000);// 或者在外面包一层,这样对 obj.list 就可以整体赋值了
const obj = reactive<{ list: string[] }>({list: [],
});
setTimeout(() => {obj.list = ["a", "b", "c"];
}, 2000);

二、将 reactive 的值 设置为 readonly

  • 设置为 readonly 后不可修改
  • 修改 reactive 源数据,readonly 的值也会受影响
const info = reactive({name: "xiaoman",
});
const rd = readonly(info);// 设置为 readonly 后不可修改
// rd.name = 'daman'// 但是可以修改它的源数据
info.name = "blue";
console.log("修改源数据,readonly的值也会受影响", info, rd);

可以看到,两者的值都被修改了:

在这里插入图片描述

三、shallowReactive

  • 与上一篇 ref 全家桶 中 shallowRef 十分相似,都是浅层的响应式
  • 修改第一层会触发视图更新,修改深层 不会触发视图更新
  • 有其他触发视图更新的操作,也会顺带将其更新

① reactive 是深层的响应式,视图会立刻更新

const obj2 = reactive({foo: {bar: {name: "xiaoman",},},
});
setTimeout(() => {obj2.foo.bar.name = "blue222222222";
}, 1000);

在这里插入图片描述

② shallowReactive 是浅层的响应式

const obj3 = shallowReactive({foo: {bar: {name: "xiaoman",},},
});

1、修改浅层才会触发响应式,会立刻更新:

setTimeout(() => {obj3.foo = {bar: {name: "小满",},};
}, 1000);

2、修改深层可以打印到新值,但视图不会立刻更新:

setTimeout(() => {// 修改深层不会触发更新obj3.foo.bar.name = "blue3333333333";console.log("obj3", obj3); // 打印成功,但是视图不会更新
}, 1000);

控制台:

在这里插入图片描述

视图:

在这里插入图片描述

3、会被其他有视图更新的操作,顺带着一起更新掉

setTimeout(() => {// 修改深层不会触发更新obj3.foo.bar.name = "blue3333333333";console.log("obj3", obj3);obj2.foo.bar.name = "blue555555"; // obj2 是 reactive,触发更新视图
}, 1000);

在这里插入图片描述

四、源码学习

主要关注 createReactiveObject 函数的逻辑

在这里插入图片描述
学习笔记:

/**** 1、reactivity.d.ts中,关于 reactive 的类型定义:* *    export declare function reactive<T extends object>(target: T): UnwrapNestedRefs<T>;*    * 	  其中 T extends object:即只能传入 object 的子类型* * 2、reactivity.cjs.prod.js中,* *      function reactive(target) {if (isReadonly(target)) {return target;}.....*      即:reactive 如果传入只读类型的,会直接返回*          *   3、createReactiveObject 函数中,*     - 若传入的不是 object 类型,会抛出警告(dev环境)并直接返回;*     - 若传入的是被 proxy 代理过的(并且不是为了将其变为只读),也会直接返回*     - 如果能从缓存中找到,则直接返回(weakMap)*     - 如果在白名单中,也会直接返回,例如 __skip__(后面会讲的 markRaw 处理过的会加一个 __skip__,会跳过proxy代理 )*     - 如果以上条件都没触发,就会进行 proxy代理**/

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

统信UOS下eclipse使用lombok报错的问题

lombok不兼容问题 lombok不支持高版本jdk&#xff0c;本人在应用商店下载eclipse安装的&#xff0c;默认用的jdk17&#xff0c;不兼容lombok插件&#xff0c;需要调整eclipse.ini配置文件&#xff0c;如下&#xff1a; #/opt/apps/org.eclipse.java-ee/files/eclipse.ini -ja…

基于Spring Boot的在线视频教育培训网站设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的在线视频教育培训网站设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java sp…

老师如何设计一个实用的分班查询系统?

暑期过后&#xff0c;学校将迎来分班工作。有些是小升初需要分班&#xff0c;有些是高一升高二需要分班。对于老师来说&#xff0c;直接将分班结果发送到班级群&#xff0c;家长找不到结果时会发送信息询问&#xff0c;放假期间老师也需要时刻盯着手机。 不过&#xff0c;聪明…

快速排序【Java算法】

文章目录 1. 概念2. 思路3. 代码实现 1. 概念 快速排序是一种比较高效的排序算法&#xff0c;采用 “分而治之” 的思想&#xff0c;通过多次比较和交换来实现排序&#xff0c;在一趟排序中把将要排序的数据分成两个独立的部分&#xff0c;对这两部分进行排序使得其中一部分所有…

ESP32-C2开发板 ESP8684芯片 兼容ESP32-C3开发

C2是一个芯片采用4毫米x 4毫米封装&#xff0c;与272 kB内存。它运行框架&#xff0c;例如ESP-Jumpstart和ESP造雨者&#xff0c;同时它也运行ESP-IDF。ESP-IDF是Espressif面向嵌入式物联网设备的开源实时操作系统&#xff0c;受到了全球用户的信赖。它由支持Espressif以及所有…

接口测试最全理论知识

1、定义&#xff1a; 接口测试是测试系统组件间接口的一种测试。 接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点&#xff0c;定义特定的交互点。 然后通过这些交互点来&#xff0c;通过一些特殊的规则也就是协议&#xff0c;来进行数据之间的交互。 测…

Games101学习笔记 -光栅化

光栅化 经过MVP矩阵和视口变换后&#xff0c;我们就可以从相机的角度看到一个和屏幕大小一致的二维平面。 那么把这个看到的二维平面应用到我们的屏幕上的过程就是光栅化。在这儿我们需要补充一个概念-像素&#xff1a; 像素&#xff1a; 一个二位数组&#xff0c;数组中每个…

通用FIR滤波器的verilog实现(内有Lowpass、Hilbert参数生成示例)

众所周知&#xff0c;Matlab 中的 Filter Designer 可以直接生成 FIR 滤波器的 verilog 代码&#xff0c;可以方便地生成指定阶数、指定滤波器参数的高通、低通、带通滤波器&#xff0c;生成的 verilog 代码也可以指定输入输出信号的类型和位宽。然而其生成的代码实在算不上美观…

Linux 的基本使用

1、Linux 是什么 Linux 是一个操作系统. 和 Windows 是 "并列" 的关系 Linux 严格意义来说只是一个 "操作系统内核". 一个完整的操作系统 操作系统内核 配套的应用程序. CentOS 和 RedHat 的关系 RedHat一直都提供源代码的发行方式&#xff0c;Cent…

SpringBoot 3.x整合Fluent Mybatis极简流程

此为基础配置&#xff0c;不包括其他高级配置&#xff0c;需要其他高级配置请查阅官方文档&#xff1a;[fluent mybatis特性总览 - Wiki - Gitee.com](https://gitee.com/fluent-mybatis/fluent-mybatis/wikis/fluent mybatis特性总览) 版本信息 Spring Boot 版本&#xff1a…

使用ffmpeg将m4a及wav等文件转换为MP3格式

要使用ffmpeg将m4a及wav等文件转换为MP3格式&#xff0c;您可以按照以下步骤进行操作&#xff1a; 安装 ffmpeg 确保您已经安装了ffmpeg软件。如果没有安装&#xff0c;请访问ffmpeg的官方网站https://ffmpeg.org/ 并按照说明进行安装。 Win10 / Win11 可以通过 winget 命令…

【递归算法实践】验证二叉搜索树

目录 1. 递归算法 2. 递归实现验证二叉搜索树 3. 递归解法的实现逻辑 4. 递归实现的实例分析 1. 递归算法 递归是一种通过函数自身调用来解决问题的算法&#xff0c;它可以使代码更加简洁和优雅&#xff0c;同时也能够解决许多复杂的问题。在递归中&#xff0c;函数会不断…