当前位置: 首页 > news >正文

说一下 toRef、toRefs,以及他们的区别

toRef:创建一个新的Ref变量,转换Reactive对象的某个字段为Ref变量
toRefs:创建一个新的对象,它的每个字段都是Reactive对象各个字段的Ref变量


说一下toRef
先定义一个reactive对象

interface Member {id: numbername: string
}
const userInfo: Member = reactive({id: 1,name: 'White'
})
console.log('userInfo=', userInfo)

如果想转换userInfo对象的name这个字段为Ref变量,可以进行如下操作:let nameR = toRef(userInfo, 'name')
此时,这个nameR是一个Ref变量,
所以,之后在读取和赋值时,就要使用nameR.value来操作,
所以,在重新给nameR赋值时,会同时更新nameRuserInfo.name的值

let nameR = toRef(userInfo, 'name')
console.log('nameR是一个Ref变量,值=', nameR.value)/**
* @name editNameR
* @description 修改 nameR 的值
*/
const editNameR = () => {nameR.value = 'edit-White'// 可以看到,在重新给`nameR`赋值后,`nameR` 和 `userInfo.name`的值都同时更新了console.log('edit - nameR=', nameR.value)console.log('edit - userInfo=', userInfo)
}

toRef也可以接收一个数组,此时第二个参数,是数组的下标

let wordList = reactive(['a', 'b', 'c'])
let a = toRef(wordList, 0)
console.log('a=', a.value) // a
console.log('wordList[0]=', wordList[0]) // a

对象 - 设置默认值
如果 Reactive 对象上有一个属性本身没有初始值,可以传递第三个参数进行设置(默认值仅对 Ref 变量有效)

interface MemberCopy {id: numbername: stringage?: number // age属性,因为是可选的,因此默认值会是`undefined`
}
// 声明变量时,省略`age`属性
const theInfo: MemberCopy = reactive({id: 1,name: 'Black'
})// 此时,为了避免程序运行错误,可以指定一个初始值,但初始值仅对 Ref 变量有效,不会影响 Reactive 字段的值
let age = toRef(theInfo, 'age', 18)
console.log('age=', age.value) // age= 18
console.log('theInfo.age=', theInfo.age) // theInfo.age= undefined// 除非重新赋值,才会使两者同时更新
age.value = 25
console.log(age.value) // 25
console.log(theInfo.age) // 25

数组 - 设置默认值

const words = reactive(['a', 'b', 'c'])// 当下标对应的值不存在时,返回`undefined`
const d = toRef(words, 3)
console.log(d.value) // undefined
console.log(words[3]) // undefined// 设置了默认值之后,就会对 Ref 变量使用默认值, Reactive 数组此时不影响
const e = toRef(words, 4, 'e')
console.log(e.value) // e
console.log(words[4]) // undefined

还有一个不推荐的特殊用法,
toRef 的过程中,如果使用了原对象上不存在的 key ,那么定义出来的 Ref变量的.value值将会是 undefined

举个例子
// 众所周知,White 是没有女朋友的
const girlfriend = toRef(userInfo, 'girl')
console.log('girlfriend=', girlfriend.value) // girlfriend= undefined
console.log('userInfo.girlfriend=', userInfo.girl) // userInfo.girl= undefined
// 此时 userInfo 对象上只有两个 Key
console.log(Object.keys(userInfo)) // ['id', 'name']/*如果,对这个不存在的`key的Ref变量(girlfriend)`进行赋值,那么原来的`Reactive对象(userInfo)`也会同步增加这个key(girl),其值也会同步更新。
*/
girlfriend.value = 'Marry'
console.log('girlfriend=', girlfriend.value) // girlfriend= Marry
console.log('userInfo.girl=', userInfo.girl) // userInfo.girlfriend= Marry
console.log('看看userInfo的属性=', userInfo) // Proxy的girl、id、name

为什么强调不要在 TypeScript 里使用呢?因为在编译时,无法通过 TypeScript 的类型检查
如果非用不可,可以考虑使用any类型,如下:1、2、3

// 1、将该类型直接指定为 `any`
type Member = any
// 当然一般都是 `const userInfo: any`// 2、或者保持接口类型的情况下,允许任意键值
interface Member {[key: string]: any
}// 3、使用 `Record` 也是同理
type Member = Record<string, any>



说一下toRefs:
与toRef不同,toRefs只接收一个参数(一个reactive变量)

interface People {id: numbername: string
}// 声明一个`Reactive`变量,此时 `theKing`的TS类型是:const theKing: People
const theKing: People = reactive({id: 1,name: 'Black'
})
console.log('theKing=', theKing)// 传给`toRefs`作为入参,此时,这个新的`useToRefs`变量的TS类型就不再是`People`了,而是:const useToRefs: ToRefs<People>
const useToRefs = toRefs(theKing)
console.log('useToRefs=', useToRefs)// 也可以重新编写一个新的类型来指定它,因为每个字段都是与原来关联的 Ref 变量,所以也可以这样声明:
interface newPeople {id: Ref<number>name: Ref<string>
}
const useToRefsCopy: newPeople = toRefs(theKing)
console.log('useToRefsCopy=', useToRefsCopy)话都到这了,其实,日常使用时并不需要手动指定其类型, TypeScript会自动推导,可以节约非常多的开发工作量

对数组进行转换

const charList = reactive(['a', 'b', 'c'])
const charListRefs = toRefs(charList)
console.log('charListRefs=', charListRefs)
console.log('charListRefs[0]=', charListRefs[0].value) // charListRefs[0]= a

解构与赋值,
这一点和直接解构 Reactive 变量有非常大的不同,直接解构 Reactive 变量,得到的是一个普通的变量,不再具备响应

// 用 `toRefs` 转换后的 `Reactive对象或数组` 支持ES6的解构,并且`不会失去响应性`,因为解构后的每一个变量都具备响应性。
const { name } = toRefs(theKing)
console.log('name=', name.value) // name= Black// 此时,对解构出来的变量重新赋值,原来的变量也会同步更新
name.value = 'Tom'
console.log('重新赋值后-name=', name.value) // 重新赋值后-name= Tom
console.log('重新赋值后-theKing', theKing.name) // 重新赋值后-theKing Tom// ---------------------------- 看下面这个例子 ----------------------------/*以一个计算器函数为例,这一次将其修改为内部有一个 Reactive 的数据状态中心,在函数返回时解构为多个 Ref 变量,这样在调用 useCalculator 函数时,可以通过解构直接获取到 Ref 变量,不需要再进行额外的转换工作。
*/
interface CalculatorState {num: number,step: number // 每次计算时要增加的幅度
}
// 声明一个 “使用计算器” 的函数
const useCalculator = () => {// 通过数据中心的形式,即中管理内部变量const state: CalculatorState = reactive({num: 0,step: 10})const add = () => {state.num += state.step}return {...toRefs(state),add}
}// 解构出来的 `num` 和 `step` 都是 Ref 变量
const { num, step, add } = useCalculator()
console.log('num=', num.value) // num= 0
console.log('step=', step.value) // step= 10
// 调用计算器的方法,数据也是会得到响应式更新
add()
console.log('调用add()方法之后,num=', num.value) // 调用add()方法之后,num= 10

相关文章:

说一下 toRef、toRefs,以及他们的区别

toRef&#xff1a;创建一个新的Ref变量&#xff0c;转换Reactive对象的某个字段为Ref变量 toRefs&#xff1a;创建一个新的对象&#xff0c;它的每个字段都是Reactive对象各个字段的Ref变量 说一下toRef 先定义一个reactive对象 interface Member {id: numbername: string } c…...

修改Android Studio默认的gradle目录

今天看了一下&#xff0c;gradle在C盘占用了40多G。我C盘是做GHOST的&#xff0c;放在这里不方便。所以就要修改。 新建目录名&#xff08;似乎无必要&#xff09; ANDROID_SDK_HOMEG:\SOFTWARES\android-sdk GRADLE_USER_HOMEG:\SOFTWARES\.gradle 修改目录 File->Setti…...

鲁大师电动车智能化测评报告第二十三期:实测续航95km,九号Q90兼顾个性与实用

鲁大师第二十三期智能化电动车测评排行榜数据来源于鲁大师智慧实验室,测评的车型均为市面上主流品牌的主流车型。截止目前,鲁大师智能化电动车测评的车型高达130余台,且还在不断增加和丰富中。 一、测评依据 鲁大师电动车智能化测评体系包含车辆的状态采集与管理硬件系统、车辆…...

初始化项目骨架(Web3项目一实战之一)

暌违将近一年的时光,也该是时候来几个项目实践。要不,当再次翻看 玩以太坊链上项目的必备技能(…solidity之旅X) ,却未曾见有关于 Web3 项目的实战博文,不免让人唏嘘! 其实,在我敲下玩以太坊链上项目的必备技能这些文字时,心中早有了势必要弄出一个Web3的项目(当然,通…...

在opencv OpenCV中打开相机摄像头,用分水岭算法实时实现图像的分割与提取

import cv2 import numpy as np# 定义回调函数 def callback(x):pass# 打开摄像头 cap cv2.VideoCapture(0)# 创建窗口和控件 cv2.namedWindow(image) cv2.createTrackbar(threshold, image, 0, 255, callback)# 初始化参数 bgdModel np.zeros((1, 65), np.float64) fgdModel…...

CodeWhisperer 的正确使用

1、重点&#xff1a; 重点1&#xff1a; 推出 Amazon Bedrock。这项新服务允许用户通过 API 访问来自 AI21 Labs、Anthropic、Stability AI 和亚马逊的基础模型。&#xff08;Anthropic 就是之前跟 ChatGPT 掰手腕的 Claude 的模型。Stability AI 就是 Stable Diffusion 背后的…...

selenium xpath定位

selenium-xpath定位 <span style"background-color:#2d2d2d"><span style"color:#cccccc"><code class"language-javascript">element_xpath <span style"color:#67cdcc"></span> driver<span styl…...

「我在淘天做技术」音视频技术及其在淘宝内容业务中的应用

作者&#xff1a;李凯 一、前言 近年来&#xff0c;内容电商似乎已经充分融入到人们的生活中&#xff1a;在闲暇时间&#xff0c;我们已经习惯于拿出手机&#xff0c;从电商平台的直播间、或者短视频链接下单自己心仪的商品。 尽管优质的货品、实惠的价格、精致的布景、有趣的…...

el-input 输入后失去焦点

说了是无情&#xff0c;写了更无情&#xff0c;你说你看了不点赞是不是更绝情&#xff1f;遇到这种神奇的BUG&#xff0c;也是大家无奈的神情。 来分析看代码&#xff1a; <div class"card-item input-item" :class"{ w-100: followRadio 2 }"v-for&…...

docker创建并访问本地前端

docker创建并访问本地前端&#xff0c;直接上命令&#xff1a; 安装nginx镜像&#xff1a; docker pull nginx 查看已安装的nginx&#xff1a; docker images 创建DockerFile文件&#xff0c;直接在当前文件夹种创建 touch Dockerfile 在Dockerfile写入内容&#xff1a; F…...

数据结构之单链表基本操作

&#x1f937;‍♀️&#x1f937;‍♀️&#x1f937;‍♀️ 今天给大家分享的是单链表的基本操作。 清风的个人主页 &#x1f389;欢迎&#x1f44d;点赞✍评论❤️收藏 &#x1f61b;&#x1f61b;&#x1f61b;希望我的文章能对你有所帮助&#xff0c;有不足的地方还请各位…...

Python 实践

文章目录 一、HttpRequests 一、Http Requests python——Request模块...

使用easyui前端框架快速构建一个crud应用

本篇文章将会详细介绍jquery easyui前端框架的使用&#xff0c;通过创建一个crud应用来带大家快速掌握easyui的使用。 easyui是博主最喜欢的前端框架&#xff0c;没有之一&#xff0c;因为它提供了多种主题&#xff0c;而且有圆润的各种组件。 一、快速开始 easyui的官网地址&…...

Logback从添加依赖,到配置给中打印级别,archive相关信息配置,在项目中的常见的用法,一个完整的过程

添加Logback依赖&#xff1a; 在您的Maven或Gradle项目中&#xff0c;添加Logback依赖。例如&#xff0c;在Maven中&#xff0c;可以将以下依赖添加到pom.xml文件中&#xff1a; <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-c…...

虚假内容检测,谣言检测,不实信息检测,事实核查;纯文本,多模态,多语言;数据集整理

本博客系博主个人理解和整理所得&#xff0c;包含内容无法详尽&#xff0c;如有补充&#xff0c;欢迎讨论。 这里只提供数据集相关介绍和来源出处&#xff0c;或者下载地址等&#xff0c;因版权原因不提供数据集所含的元数据。如有需要&#xff0c;请自行下载。 “Complete d…...

数据结构:单链表

文章目录 &#x1f349;前言&#x1f349;基本概念&#x1f349;链表的分类&#x1f34c;单链表节点的结构&#x1f34c;创建节点&#x1f34c;打印链表&#x1f34c;插入和删除&#x1f95d;尾插&#x1f95d;头插&#x1f95d;尾删&#x1f95d;头删&#x1f95d;指定位置之前…...

官媒代运营:让大众倾听品牌的声音

在当今数字时代&#xff0c;媒体的影响力和多样性远远超出了以往的范畴。品牌和企业越来越依赖媒体来传播信息、建立声誉以及与大众互动。而媒体矩阵成为了现代品牌传播的关键策略&#xff0c;使大众能够倾听品牌的声音。媒体矩阵&#xff1a;多元化的传播渠道 媒体矩阵是指利…...

postgresql 实现计算日期间隔排除周末节假日方案

前置条件&#xff1a;需要维护一张节假日日期表。例如创建holiday表保存当年假期日期 CREATE TABLE holiday (id BIGINT(10) ZEROFILL NOT NULL DEFAULT 0,day TIMESTAMP NULL DEFAULT NULL,PRIMARY KEY (id) ) COMMENT假期表 COLLATEutf8mb4_0900_ai_ci ;返回日期为xx日xx时x…...

金融工作怎么做?低代码如何助力金融行业

10月30日至31日&#xff0c;中央金融工作会议在北京举行。金融是国民经济的“血脉”&#xff0c;是国家核心竞争力的重要组成部分。会议指出&#xff0c;党的十八大以来&#xff0c;在党中央集中统一领导下&#xff0c;金融系统有力支撑经济社会发展大局&#xff0c;坚决打好防…...

基于springboot实现智慧外贸平台系统【项目源码+论文说明】计算机毕业设计

基于springboot实现智慧外贸平台系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把智慧外贸管理与现在网络相结合&#xff0c;利用java技术建设智慧外贸平台&#xff0c;实现智慧外贸的信息化。则对于进一步提高智慧外贸管理发展&#xff0c;丰富智慧外贸管理经验能…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...