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

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

前言

本篇主要学习几个 api 及相关源码:

  • toRef
  • toRefs
  • toRaw

一、toRef

  • toRef(reactiveObj, key)
    • 接收两个参数,第一个是 响应式对象,第二个是 指定的key
    • 作用:将 响应式对象一部分也变为响应式,通过 .value 修改
  • toRef 对 非响应式 对象无能为力,修改后 视图不会更新
  • 直接解构 reactiveObj,不使用 toRef,会使解构出的值 丧失响应式
  • 应用场景:某个单独的 属性key 需要被单独使用,并 希望它是响应式的

① 对非响应式对象无能为力

<div class="">hobby:{{ hobby }}</div>
<button @click="change">修改</button>
//  普通对象
const man = {name: "xiaoman",age: 18,hobby: "ball",
};
const hobby = toRef(man, "hobby"); // 对普通对象使用,修改后仅修改值 但不更新视图const change = () => {hobby.value = "sing";console.log("hobby", hobby); // Ref<"sing">,但视图不更新
};

打印更新:
在这里插入图片描述

视图不更新:

在这里插入图片描述

② 将响应式对象的一部分也变为响应式

<div class="">hobby2:{{ hobby2 }}</div>
<button @click="change">修改</button>
// reactive 响应式对象
const man2 = reactive({name: "xiaoman",age: 18,hobby: "ball",
});
const hobby2 = toRef(man2, "hobby");const change = () => {hobby2.value = "dance";console.log("hobby2", hobby2, man2) // hobby2 和 man2 都会更新,视图也会更新
};

打印:

在这里插入图片描述

视图更新:

在这里插入图片描述

③ 直接解构响应式对象

直接解构 响应式对象,不使用 toRef,会使解构出的值 丧失响应式

// reactive 响应式对象
const man2 = reactive({name: "xiaoman",age: 18,hobby: "ball",
});
const { age } = man2; // 直接解构会丧失响应式
console.log("直接解构 age------", age);

解构出的就只是一个普通的值:

在这里插入图片描述

二、toRefs

  • toRefs(reactiveObj)
    • 和 toRef 作用一样,只是不再指定某个key,而是把全部属性都变为响应式
    • 也是需要 传入响应式对象,之后若对其解构,解构出的也是响应式对象
  • 外层不再是响应式,内部的每一个key才是响应式

① 简单实现 toRefs 的源码

其实就是定义一个循环,循环体中 调用 toRef

const toRefsCopy = <T extends object>(obj: T) => {const map: any = {};for (let key in obj) {map[key] = toRef(obj[key]);}return map;
};

② toRefs 使用

<div>refs:{{ refs }}</div>
<div>refs2:{{ refs2 }}</div>
<button @click="change2">修改</button>
const blue = reactive({name: "blue",age: 19,
});const refs = toRefsCopy(blue);
const refs2 = toRefs(blue);
console.log("refs---", refs, refs2);const change2 = () => {// 解构出的每一个key都是响应式const { age } = refs2;age.value = 24;console.log("toRefs", refs, age);
};

toRefs 和 toRefsCopy 处理过后,每个key都是响应式:

在这里插入图片描述
直接解构出的 key 也是响应式,会立刻更新:

在这里插入图片描述

三、toRaw

  • toRaw(reactiveObj)
    • 同样接收一个 响应式对象
    • 作用:toRaw 使 响应式对象 变为 普通原始对象
  • 取出 响应式对象__v_raw 对应的值,跟 toRaw 之后的结果相同(__v_raw 是源码内部的操作)
const people = reactive({name: "bill",age: 12,
});// 打印结果:people 是具有响应式的对象,toRaw 后就变成了普通原始对象
console.log("toRaw-------", people, toRaw(people));// 取出 __v_raw 对应的值,跟 toRaw 的结果相同
console.log("__v_raw-------", people["__v_raw"]);

在这里插入图片描述

四、源码学习

源码贴图:

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

源码理解记录:

/***(reactivity.cjs.prod.js)搜索 function toRef 即可找到** 1、function toRef (source, key, defaultValue)*    - 先判断 isRef,true的话直接返回*    - 再判断是不是函数类型,GetterRefImpl 内部仍然是直接返回,但会增加一些必要的标记(__v_isRef、__v_isReadonly)**    - 再判断是不是object,是的话走进 propertyToRef*        - 看 source[key] 是否满足 isRef,*            true的话直接返回(已经设置过响应式了)*            否则走进 ObjectRefImpl,这就是 toRef 的核心方法*        - ObjectRefImpl 与 RefImpl(ref) 内部同样有 get、set方法,*          但是区别在于 ObjectRefImpl 没有收集依赖(track)、触发更新(trigger) 的操作*          所以 toRef 对普通对象来讲没有响应式,只对已经有响应式的对象有用**    - 上述类型都不属于的话,直接 ref(source)**** 2、function toRefs (object)**    - 和上面自己写的 toRefsCopy 思路基本一致*        - 先初始化一下,[]或者{}*        - 然后循环,*                判断每个值 若 isRef=true 直接返回*                否则都 走进 ObjectRefImpl 中变为 ref 类型*** 3、function toRaw(observed)**    - 判断 observed 是否存在 __v_raw ,存在的话继续递归 toRaw,否则直接返回 observed*    - 取出的结果就是 不带 __v_raw 的原始普通对象***/

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

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

相关文章

嘉楠勘智k230开发板上手记录(四)--HHB神经网络模型部署工具

按照K230_AI实战_HHB神经网络模型部署工具.md&#xff0c;HHB文档&#xff0c;RISC-V 编译器和模拟器安装来 一、环境 1. 拉取docker 镜像然后创建docker容器并进入容器 docker pull hhb4tools/hhb:2.4.5 docker run -itd --namehhb2_4 -p 22 "hhb4tools/hhb:2.4.5"…

【CSS】背景图定位问题适配不同机型

需求 如图, 实现一个带有飘带的渐变背景 其中头像必须显示飘带凹下去那里 , 需要适配不同的机型, 一不下心容易错位 实现 因为飘带背景是版本迭代中更新的, 所以飘带和渐变背景实则两个div 飘带切图如下 , 圆形部分需要契合头像 <view class"box-bg"><…

Linux ——实操篇

Linux ——实操篇 前言vi 和 vim 的基本介绍vi和vim常用的三种模式正常模式插入模式命令行模式 vi和vim基本使用各种模式的相互切换vi和vim快捷键关机&重启命令基本介绍注意细节 用户登录和注销基本介绍使用细节 用户管理基本介绍添加用户基本语法应用案例细节说明 指定/修…

获取接口的所有实现

一、获取接口所有实现类 方法1&#xff1a;JDK自带的ServiceLoader实现 ServiceLoader是JDK自带的一个类加载器&#xff0c;位于java.util包当中&#xff0c;作为 A simple service-provider loading facility。 &#xff08;1&#xff09;创建接口 package com.example.dem…

Springboot中拦截GET请求获取请求参数验证合法性

目录 目的 核心方法 完整代码 创建拦截器 注册拦截器 测试效果 目的 在Springboot中创建拦截器拦截所有GET类型请求&#xff0c;获取请求参数验证内容合法性防止SQL注入&#xff08;该方法仅适用拦截GET类型请求&#xff0c;POST类型请求参数是在body中&#xff0c;所以下面…

3.1 计算机网络和网络设备

数据参考&#xff1a;CISP官方 目录 计算机网络基础网络互联设备网络传输介质 一、计算机网络基础 1、ENIAC&#xff1a;世界上第一台计算机的诞生 1946年2月14日&#xff0c;宾夕法尼亚大学诞生了世界上第一台计算机&#xff0c;名为电子数字积分计算机&#xff08;ENIAC…

【Autolayout案例02-距离四周边距 Objective-C语言】

一、好,来看第二个案例 1.第二个案例,是什么意思呢,第二个案例,要求屏幕中间,有一个UIView UIView,是个红色的UIView UIView的大小,我不限定 但是无论你是什么屏幕下 这个UIView距离上边,始终是50 距离右边,始终是50, 距离下边,始终是50, 距离左边,始终是5…

Nginx跳转模块——location与rewrite

一、location 1、location作用 用于匹配uri&#xff08;文件、图片、视频&#xff09; uri&#xff1a;统一资源标识符。是一种字符串标识&#xff0c;用于标识抽象的或物理资源文件、图片、视频 2、locatin分类 1、精准匹配&#xff1a;location / {...} 2、一般匹配&a…

PROFINET转DeviceNet网关普通网线能代替profinet吗

捷米JM-DNT-PN这款神器&#xff0c;连接PROFINET和DeviceNet网络&#xff0c;让两边数据轻松传输。 这个网关不仅从ETHERNET/IP和DEVICENET一侧读写数据&#xff0c;还可以将缓冲区数据交换&#xff0c;这样就可以在两个网络之间愉快地传递数据了&#xff01;而且&#xff0c;…

虚幻引擎游戏开发过程中,游戏鼠标如何双击判定?

UE虚幻引擎对于游戏开发者来说都不陌生&#xff0c;市面上有47%主机游戏使用虚幻引擎开发游戏。作为是一款游戏的核心动力&#xff0c;它的功能十分完善&#xff0c;囊括了场景制作、灯光渲染、动作镜头、粒子特效、材质蓝图等。本文介绍了虚幻引擎游戏开发过程中游戏鼠标双击判…

springboot+mybatis实现简单的增、删、查、改

这篇文章主要针对java初学者&#xff0c;详细介绍怎么创建一个基本的springboot项目来对数据库进行crud操作。 目录 第一步&#xff1a;准备数据库 第二步&#xff1a;创建springboot项目 方法1&#xff1a;通过spring官网的spring initilizer创建springboot项目 方法2&am…

SQL SERVER ip地址改别名

SQL server在使用链接服务器时必须使用别名&#xff0c;使用ip地址就会把192.188.0.2这种点也解析出来 解决方案&#xff1a; 1、物理机ip 192.168.0.66 虚拟机ip 192.168.0.115 2、在虚拟机上找到 C:\Windows\System32\drivers\etc 下的 &#xff08;我选中的文件&a…

C#与C/C++交互(1)——需要了解的基础知识

【前言】 C#中用于实现调用C/C的方案是P/Invoke&#xff08;Platform Invoke&#xff09;&#xff0c;让托管代码可以调用库中的函数。类似的功能&#xff0c;JAVA中叫JNI&#xff0c;Python中叫Ctypes。 常见的代码用法如下&#xff1a; [DllImport("Test.dll", E…

修改IDEA的idea.vmoptions参数导致IDEA无法打开(ReservedCodeCacheSize)

事发原因 Maven导依赖的时候OOM&#xff0c;因此怀疑是内存太小&#xff0c;尝试修改idea.vmoptions的参数&#xff0c;然后发现IDEA重启后打不开了&#xff0c;卸载重装后也无法打开。。。 实际上如果导包爆出OOM的话应该调整下图参数&#xff0c;不过这都是后话了 解决思路…

【从零开始学习JAVA | 第四十四篇】TCP协议中的握手与挥手

前言&#xff1a; TCP&#xff08;传输控制协议&#xff09;作为计算机网络中的重要协议&#xff0c;扮演着确保数据可靠传输的角色。在TCP的通信过程中&#xff0c;握手与挥手问题是不可忽视的关键环节。握手是指在建立连接时&#xff0c;客户端与服务器相互确认彼此的身份并…

【学习FreeRTOS】第1章——FreeRTOS入门

1.裸机与RTOS介绍 1.1.裸机与RTOS引入&#xff08;举例&#xff09; 设定情景&#xff1a;小明同学一边打游戏一边恢复女友消息&#xff0c;中途突然肚子疼要上医院 裸机的抽象表达 当紧急情况时&#xff0c;如果当前正在打游戏&#xff0c;那么小明只能打游戏和回复信息的流…

Spring 事务管理

目录 1. 事务管理 1.1. Spring框架的事务支持模型的优势 1.1.1. 全局事务 1.1.2. 本地事务 1.1.3. Spring框架的一致化编程模型 1.2. 了解Spring框架的事务抽象&#xff08;Transaction Abstraction&#xff09; 1.2.1. Hibernate 事务设置 1.3. 用事务同步资源 1.3.1…

PHP最简单自定义自己的框架创建目录结构(二)

1、mvc目录结构 2、目录解释 KJ&#xff1a;项目名称 core&#xff1a;框架核心目录 KJ.php 框架运行入口 index: 框架模块 controller:模块控制器 model:模块模型数据库操作 view:页面显示html index.php:index模块框架入口 3、index.php框架入口文件引入框架 <?php r…

虚拟世界探索:科技之下的未来可能性

随着科技的飞速发展&#xff0c;人们对于虚拟世界的憧憬和探索也日益加深。虚拟世界&#xff0c;那是一个超越现实的概念&#xff0c;一个充满想象力和创造力的领域。然而&#xff0c;虚拟世界究竟有可能实现吗&#xff1f;这是一个引人深思的问题。 虚拟世界&#xff0c;首先让…

Vue.js2+Cesium1.103.0 六、标绘与测量

Vue.js2Cesium1.103.0 六、标绘与测量 点&#xff0c;线&#xff0c;面的绘制&#xff0c;可实时编辑图形&#xff0c;点击折线或多边形边的中心点&#xff0c;可进行添加线段移动顶点位置等操作&#xff0c;并同时计算出点的经纬度&#xff0c;折线的距离和多边形的面积。 De…