Vue3关于响应式数据类型(ref、reactive、toRef、以及toRefs)

ref

  • 接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的 property .value。
  • 类型

function ref<T>(value: T): Ref<UnwrapRef<T>>interface Ref<T> {value: T
}

  • 详细信息

ref 对象是可更改的,也就是说你可以为 .value 赋予新的值。它也是响应式的,即所有对 .value 的操作都将被追踪,并且写操作会触发与之相关的副作用。
如果将一个对象赋值给 ref,那么这个对象将通过 reactive() 转为具有深层次响应式的对象。这也意味着如果对象中包含了嵌套的 ref,它们将被深层地解包。
若要避免这种深层次的转换,请使用 shallowRef() 来替代

  • 示例

import { ref } from 'vue
const count = ref<number>(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1

reactive

返回一个对象的响应式代理

  • 类型

function reactive<T extends object>(target: T): UnwrapNestedRefs<T>

  • 详细信息

响应式转换是“深层”的:它会影响到所有嵌套的 property。一个响应式对象也将深层地解包任何 ref property,同时保持响应性。

值得注意的是,当访问到某个响应式数组或 Map 这样的原生集合类型中的 ref 元素时,不会执行 ref 的解包。

若要避免深层响应式转换,只想保留对这个对象顶层次访问的响应性,请使用 shallowReactive() 作替代。

返回的对象以及其中嵌套的对象都会通过 ES Proxy 包裹,因此不等于源对象,建议只使用响应式代理,避免依赖于原始对象。

  • 示例

import { reactive } from 'vue'
interface Obj {count: number
}
const obj = reactive<Obj>({ count: 0 })
obj.count++

  • ref 的解包:

const count = ref(1)
const obj = reactive({ count })// ref 会被解包
console.log(obj.count === count.value) // true// 会更新 `obj.count`
count.value++
console.log(count.value) // 2
console.log(obj.count) // 2// 也会更新 `count` ref
obj.count++
console.log(obj.count) // 3
console.log(count.value) // 3

  • 注意当访问到某个响应式数组或 Map 这样的原生集合类型中的 ref 元素时,不会执行 ref 的解包

const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value
console.log(map.get('count').value)

  • 将一个 ref 赋值给为一个 reactive 属性时,该 ref 会被自动解包:

const count = ref(1)
const obj = reactive({})obj.count = countconsole.log(obj.count) // 1
console.log(obj.count === count.value) // true

toRef()

可用于为响应式对象上的 property 创建 ref。这样创建的 ref 与其源 property 保持同步:改变源 property 将更新 ref,反之亦然。

  • 类型

function toRef<T extends object, K extends keyof T>(object: T,key: K,defaultValue?: T[K]
): ToRef<T[K]>type ToRef<T> = T extends Ref ? T : Ref<T>

  • 示例

const state = reactive({foo: 1,bar: 2
})
const fooRef = toRef(state, 'foo')
// 更改该 ref 会更新源属性
fooRef.value++
console.log(state.foo) // 2
// 更改源属性也会更新该 ref
state.foo++
console.log(fooRef.value) // 3

  • 请注意,这不同于:

const fooRef = ref(state.foo)
//上面这个 ref 不会和 state.foo 保持同步,因为这个 ref() 接收到的是一个纯数值。//toRef() 这个函数在你想把一个 prop 的 ref 传递给一个组合式函数时会很有用

<script setup>
import { toRef } from 'vue'const props = defineProps(/* ... */)// 将 `props.foo` 转换为 ref,然后传入
// 一个组合式函数
useSomeFeature(toRef(props, 'foo'))
</script>

当 toRef 与组件 prop 结合使用时,关于对 prop 做出更改的通用限制依然有效。尝试将新的值传递给 ref 等效于尝试直接更改 prop,这是不允许的。在这种场景下,你可能可以考虑使用带有 get 和 set 的 computed 替代。

即使源 property 当前不存在,toRef() 也会返回一个可用的 ref。这让它在处理可选 prop 的时候格外实用,而可选 prop 在使用 toRefs 时不会被保留。

toRefs()

将一个响应式对象转换为一个普通对象,这个普通对象的每个 property 都是指向源对象相应 property 的 ref。每个单独的 ref 都是使用 toRef() 创建的。

  • 类型

function toRefs<T extends object>(object: T
): {[K in keyof T]: ToRef<T[K]>
}type ToRef = T extends Ref ? T : Ref<T>

  • 示例

const state = reactive({foo: 1,bar: 2
})const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:{foo: Ref<number>,bar: Ref<number>
}
*/// 这个 ref 和源属性已经“链接上了”
state.foo++
console.log(stateAsRefs.foo.value) // 2stateAsRefs.foo.value++
console.log(state.foo) // 3

当从组合式函数中返回响应式对象时,toRefs 大有作为,使用它,消费者组件可以解构/扩展返回的对象而不会失去响应性:

function useFeatureX() {const state = reactive({foo: 1,bar: 2})// ...基于状态的操作逻辑// 在返回时都转为 refreturn toRefs(state)
}// 可以解构而不会失去响应性
const { foo, bar } = useFeatureX()

toRefs 在调用时只会为源对象上可以列举出的 property 创建 ref。如果要为可能还不存在的 property 创建 ref,请改用 toRef 。


---------------------
作者:Oxygen_liu
来源:CSDN
原文:https://blog.csdn.net/qq_41400354/article/details/124121777
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

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

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

相关文章

智能路由器-OpenWRT 系列四 (挂载移动设备)

每次ssh登陆OpenWRT安装新软件时&#xff0c;都必须更新opkg opkg update安装驱动 为了可以识别U盘/移动硬盘&#xff0c;必须安装相关的驱动。 一类是usb相关的驱动 opkg install kmod-usb-core #usb驱动 opkg install kmod-scsi-core #SCSI总线驱动 opkg install kmod-scs…

jstl 处理Date 时间

1、引入 <% taglib prefix"fmt" uri"http://java.sun.com/jsp/jstl/fmt" %> <fmt:formatDate value"${Date}" pattern"yyyy-MM" /><!-- 这里的value只能是date类型--> pattern 随意发挥了&#xff01;转载于:https:…

windows系统vscode检查更新菜单消失且不能自动更新(1.70.0不能自动更新到1.70.2

翻了半天vscode的issues中终于找到了https://github.com/microsoft/vscode/issues/157624 解决方案 不能用管理员身份运行vscode&#xff0c;不然就没有检查更新菜单&#xff0c;关闭后重启vscode就有更新菜单了 相关回答 翻译一下&#xff0c;就是vscode分用户类型和系统类型两…

LinkedHashMap的实现原理

1. LinkedHashMap概述&#xff1a; LinkedHashMap是Map接口的哈希表和链接列表实现&#xff0c;具有可预知的迭代顺序。此实现提供所有可选的映射操作&#xff0c;并允许使用null值和null键。此类不保证映射的顺序&#xff0c;特别是它不保证该顺序恒久不变。 LinkedHashMap…

验证-表单令牌

表单令牌验证规则支持对表单的令牌验证&#xff0c;首先需要在你的表单里面增加下面隐藏域&#xff1a;或者然后在你的验证规则中&#xff0c;添加token验证规则即可&#xff0c;例如&#xff0c;如果使用的是验证器的话&#xff0c;可以改为&#xff1a;如果你的令牌名称不是_…

WPF 用户控件分享之边上带输入框的圆圈

WPF 用户控件分享之边上带输入框的圆圈独立观察员 2022 年 8 月 20 日最近有这样一个需求&#xff0c;有一圈圆形&#xff0c;每个圆形边上有个输入框&#xff0c;以下是完成后的效果图&#xff1a;拿到这个需求后&#xff0c;分析界面上每个圆形和输入框应该视为一个用户控件&…

总统与乞丐

一位总统带着孙子散步&#xff0c;有个乞丐向他鞠躬敬礼&#xff0c;总统马上驻足还礼&#xff0c;而且弯腰更深。孙子不解:“他只是个乞丐啊&#xff01;” 总统回答&#xff1a;“我绝不允许一个乞丐比总统更有礼貌&#xff01;不要以为别人尊敬你&#xff0c;是因为你很优秀…

VUE3 v-show 引起的表单验证问题

<el-form ref"formRef" :rules"rules" :model"form" label-width"80px"><el-form-item label"任务类型" prop"TaskType"><el-radio-group v-model"form.TaskType" change"handleCh…

ThreadPoolExecutor

简述&#xff1a; 有的时候&#xff0c;系统处理很多任务&#xff0c;如何这些任务要是都是通过new Thread来做的话&#xff0c;系统就不得不常常的创建之后还要销毁Thread&#xff0c;这个是非常消耗时间而且还占用资源&#xff0c;所以我们通过创建线程池来管理我们的线程。 …

你总说时间很少

你总说时间很少 没时间看哭泣的骆驼 少了心情 你总说时间很少 没时间撩拨那爱的罗曼史 少了喜欢 你总说时间很少 没时间吮吸印度洋的水清沙白 少了勇敢 你总说时间很少 没时间寻找相伴的野马 少了感觉 可到最后 时间真的很少 有了喜欢 就少了心情 有了感觉 就少了勇敢…

Unity 将是驱动 C# 增长的引擎吗 ?

C# 在中国的采用需要一个杀手级应用的带动&#xff0c; 那么这样的一个杀手级应用是 Unity吗&#xff0c;我这里大胆推测采用CoreCLR 的新一代完全采用C#构建的Unity 将是这样的一个杀手级应用。Unity已被广泛应用于数字孪生、数字城市、数字工厂等场景&#xff0c;成为各产业加…

HTML5video 标签

属性 值 说明 autoplay autoplay 如果出现该属性&#xff0c;则视频在就绪后马上播放。 controls controls 如果出现该属性&#xff0c;则向用户显示控件&#xff0c;比如播放按钮。 preload preload 如果出现该属性&#xff0c;则视频…

Windows 超级开源实用工具:Microsoft PowerToys

实用工具集&#xff1a; Always on Top ​通过 Always on Top&#xff0c;可使用快捷键方式 (⊞ WinCtrlT) 将窗口固定在其他窗口的顶部。 ​ PowerToys Awake PowerToys Awake旨在使计算机保持唤醒状态&#xff0c;且无需管理其电源和睡眠设置。 运行耗时较长的任务时&#…

Python入门之数据类型

字符串 列表 元组 字典 转载于:https://www.cnblogs.com/py17/p/8919495.html

Kubeadm 快速搭建 k8s v1.24.1 集群(openEuler 22.03 LTS)

kubeadm 简介kubeadm 是 Kubernetes&#xff08;以下简称 k8s&#xff09;官方提供的用于快速安装部署 k8s 集群的工具&#xff0c;伴随 k8s 每个版本的发布都会同步更新&#xff0c;kubeadm 会对集群配置方面的一些实践做调整&#xff0c;通过实验 kubeadm 可以学习到 k8s 官方…

汇编试验五:编写、调试具有多个段的程序

ds 数据段放入数据正确&#xff1b; 两次push 操作后&#xff0c;ss栈段正确&#xff1b; 由于pop 操作顺序&#xff0c;ds数据段并没有发生改变&#xff1b; Source Code: assume cs:code, ds:data, ss:stackdata segmentdw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H …

SVN四部曲之SVN设置详解深入

想知道不同的设置是干什么用的&#xff0c;你只需将鼠标指针在编辑框/选项框上停留一秒钟...一个帮助提示气泡就会弹出来。 常规设置 图 4.68. 设置对话框&#xff0c;常规设置页面 这个对话框允许你指定自己喜欢的语言&#xff0c;同时也可做那些与Subversion相关的特殊设置。…

Vue3.2单文件组件setup的语法糖总结

目录 前言 setup语法糖 一、基本用法 二、data和methods 三、计算属性computed 四、监听器watch、watchEffect 五、自定义指令directive 六、import导入的内容可直接使用 七、声明props和emits 八、父组件获取子组件的数据 九、provide和inject传值 十、路由useRou…

自动判断PC端、手机端跳往不同的域名JS实现代码

输入相同域名&#xff0c;在pc端和移动端会出现不同的页面效果&#xff0c;一种是用栅格系统实现自适应&#xff0c; 更多的是设计两套不同的模板和两个二级域名或者一个主域名和一个二级域名&#xff08;就是有区别就可以了&#xff09;; js代码判断浏览器的用户代理头类别从而…

使用dotnet-monitor分析在Kubernetes的应用程序:Sidecar模式

dotnet-monitor可以在Kubernetes中作为Sidecar运行&#xff0c;Sidecar是一个容器&#xff0c;它与应用程序在同一个Pod中运行&#xff0c;利用Sidecar模式使我们可以诊断及监控应用程序。如下图所示&#xff0c;这是我们最终要实现的目标&#xff0c;通过可视化界面查看应用程…