vue3.0(六) toRef,toValue,toRefs和toRow,markRaw

文章目录

  • toRef
  • toValue
  • toRefs
  • toRow
  • markRaw
  • toRef和toRefs的区别
  • toRaw 和markRaw的用处


toRef

  • toRef 函数可以将一个响应式对象的属性转换为一个独立的 ref 对象。
  • 返回的是一个指向源对象属性的 ref 引用,任何对该引用的修改都会同步到源对象属性上。
  • 使用 toRef 时需要传入源对象和属性名作为参数。
  • 转换后的响应式可以被用于计算属性及监听器中
  1. 原对象是响应式,改变后,值改变,页面也会更新
    <template><div>{{ state.bar }}</div><div>{{ barState }}</div><button @click="mutateDeeply">修改数据</button>
    </template>
    <script lang="ts">
    import { defineComponent, reactive, toRef } from 'vue'
    export default defineComponent({setup () {const state = reactive({bar: 2})const barState = toRef(state, 'bar')function mutateDeeply () {barState.value++console.log(barState.value, state.bar)}return {mutateDeeply,state,barState}}
    })
    </script>
    

上述代码执行效果

  1. 原对象为非响应式,改变后,值会改变,但页面不会更新
    <template><div>{{ state.bar }}</div><div>{{ barState }}</div><button @click="mutateDeeply">修改数据</button>
    </template>
    <script lang="ts">
    import { defineComponent, reactive, toRef } from 'vue'
    export default defineComponent({setup () {const state = {bar: 2}const barState = toRef(state, 'bar')function mutateDeeply () {barState.value++console.log(barState.value, state.bar)}return {mutateDeeply,state,barState}}
    })
    </script>
    

上述代码执行效果

  1. 接收一个 Reactive 数组,此时第二个参数应该传入数组的下标:
  // 这一次声明的是数组const words = reactive([1, 2, 3])// 通过下标 `0` 转换第一个 itemconst a = toRef(words, 0)console.log(a.value) // 1console.log(words[0]) // 1// 通过下标 `2` 转换第三个 itemconst c = toRef(words, 2)console.log(c.value) // 3console.log(words[2]) // 3
  1. 设置默认值
  • 如果 Reactive 对象上有一个属性本身没有初始值,也可以传递第三个参数进行设置(默认值仅对 Ref 变量有效):
  • 数组也是同理,对于可能不存在的下标,可以传入默认值避免项目的逻辑代码出现问题:
    interface Member {id: numbername: string// 类型上新增一个属性,因为是可选的,因此默认值会是 `undefined`age?: number
    }// 声明变量时省略 `age` 属性
    const userInfo: Member = reactive({id: 1,name: 'Petter',
    })// 此时为了避免程序运行错误,可以指定一个初始值
    // 但初始值仅对 Ref 变量有效,不会影响 Reactive 字段的值
    const age = toRef(userInfo, 'age', 18)
    console.log(age.value)  // 18
    console.log(userInfo.age) // undefined// 除非重新赋值,才会使两者同时更新
    age.value = 25
    console.log(age.value)  // 25
    console.log(userInfo.age) // 25const numbers = reactive([1, 2, 3])// 当下标对应的值不存在时,也是返回 `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
    

toValue

  • toValue() 是一个在 3.3 版本中新增的 API。它的设计目的是将 ref 或 getter 规范化为值。如果参数是 ref,它会返回 ref 的值;如果参数是函数,它会调用函数并返回其返回值
  • 与 unref() 类似,不同的是此函数也会规范化 getter 函数。如果参数是一个 getter,它将会被调用并且返回它的返回值。
  1. 应用
    console.log(toValue(1), toValue(ref(1)), toValue(() => 1)) // 1 1 1
    
  2. 在组合式函数中规范化参数:
<template><button @click="mutateDeeply">修改数据</button>
</template>
<script lang="ts">
import { defineComponent, toValue, ref, watch } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
export default defineComponent({setup () {const num = ref(2) function mutateDeeply () {num.value++useFeature(num)}function useFeature (id: MaybeRefOrGetter<number>) {// 监听数据变化watch(() => toValue(id), newId => {// 处理 id 变更console.log(newId)})}// 这个组合式函数支持以下的任意形式:useFeature(1)useFeature(ref(1))useFeature(() => 1)return {mutateDeeply,num}}
})
</script>

toRefs

  • toRefs 函数可以将一个响应式对象转换为一个普通的对象,该对象的每个属性都是独立的 ref 对象。
  • 返回的对象可以进行解构,每个属性都可以像普通的 ref 对象一样访问和修改,而且会保持响应式的关联。
  • toRefs 的使用场景主要是在将响应式对象作为属性传递给子组件时,确保子组件可以正确地访问和更新这些属性。
  1. 与 toRef 不同, toRefs 只接收了一个参数,是一个 reactive 变量。
    <script lang="ts">
    import { defineComponent, toRefs, reactive } from 'vue'export default defineComponent({setup () {interface user {id: numbername: string}// 声明一个 Reactive 变量const userInfo: user = reactive({id: 1,name: 'Petter'})// 传给 `toRefs` 作为入参const userInfoRefs = toRefs(userInfo)console.log(userInfoRefs)console.log(userInfoRefs.id.value)console.log(userInfoRefs.name.value)return {}}
    })
    </script>
    

上述代码打印结果
可以参考vue3.0(五) reactive全家桶

toRow

Vue 创建的代理返回其原始对象。

toRaw() 可以返回由 reactive()、readonly()、shallowReactive() 或者 shallowReadonly() 创建的代理对应的原始对象。
是一个可以用于临时读取而不引起代理访问/跟踪开销,或是写入而不触发更改的特殊方法
不建议保存对原始对象的持久引用,请谨慎使用。

import { reactive, toRaw } from 'vue'
const state = reactive({count: 0
})
// 获取原始对象
const rawState = toRaw(state)
// 验证原始对象与包装后的对象是否相等
console.log(rawState === state) // false
// 改变原始对象的值
rawState.count += 1
// 验证包装后的对象是否也受到了改变

markRaw

将一个对象标记为不可被转为代理。返回该对象本身。
markRaw 方法可以将一个对象标记为“非响应式”,从而使其不会被 reactive 包裹,也就不会成为 Vue3 中的响应式对象。

import { reactive, markRaw } from 'vue'const state = reactive({count: 0,obj: {name: '张三'}
})// 标记 obj 对象为“非响应式”
markRaw(state.obj)
// obj 对象不再被 reactive 包裹
console.log(state.hasOwnProperty('__v_raw')) // false// 赋新值时不会触发响应更新
state.obj.name = '李四'
console.log(state.obj.name) // 李四

需要注意的是,一旦一个对象被标记为“非响应式”,它就无法再被 reactive 进行包裹成为响应式对象。
在使用 markRaw 方法时,需要确保这个对象在后续的代码中不需要作为响应式对象来使用或者监听其变化

toRef和toRefs的区别

  1. toRef 修改的是对象的某个属性,生成一个单独的 ref 对象。
  2. toRefs 修改的是整个对象,生成多个独立的 ref 对象集合。
  3. toRefs 适用于在组件传递属性或解构时使用,更加方便灵活,而 toRef 更适合提取单个属性进行操作。
  4. toRef 和 toRefs 都用于将响应式对象的属性转换为 ref 对象。
  5. 转换后的属性仍然保持响应式,对属性的修改会反映到源对象上。
  6. 不管是使用 toRef 还是 toRefs 将响应式对象转成普通对象,在 script 中修改和访问其值都需要通过 .value 进行。

toRaw 和markRaw的用处

  1. toRaw 可以还原数据并避免意外的响应式行为,
  2. markRaw 可以更加精细地控制哪些对象使用响应式并避免出现问题。

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

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

相关文章

Datax数据采集

一、Datax介绍 官网&#xff1a; DataX/introduction.md at master alibaba/DataX GitHub DataX 是阿里云 DataWorks数据集成 的开源版本&#xff0c;在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。 DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、…

稳定网络的诀窍:静态住宅代理解决方案

在数字化时代&#xff0c;网络稳定性对于个人和企业都至关重要。然而&#xff0c;由于多种因素的影响&#xff0c;如地理位置、网络拥堵或网络安全问题等&#xff0c;网络稳定性常常受到挑战。为了应对这些挑战&#xff0c;静态住宅代理作为一种高效且可靠的网络解决方案&#…

CCF-Csp算法能力认证, 202309-1坐标变换(其一)(C++)含解析

前言 推荐书目&#xff0c;在这里推荐那一本《算法笔记》&#xff08;胡明&#xff09;&#xff0c;需要PDF的话&#xff0c;链接如下 「链接&#xff1a;https://pan.xunlei.com/s/VNvz4BUFYqnx8kJ4BI4v1ywPA1?pwd6vdq# 提取码&#xff1a;6vdq”复制这段内容后打开手机迅雷…

路由器、交换机和网卡

大家使用VMware安装镜像之后&#xff0c;是不是都会考虑虚拟机的镜像系统怎么连上网的&#xff0c;它的连接方式是什么&#xff0c;它ip是什么&#xff1f; 路由器、交换机和网卡 1.路由器 一般有几个功能&#xff0c;第一个是网关、第二个是扩展有线网络端口、第三个是WiFi功…

龟兔赛跑(基于GUI与多线程实现)

直击龟兔赛跑现场 下面这张图是我们设计龟兔赛跑界面的初始效果与基本组成结构&#xff1a; 接下来是我仅代表我个人提出的一些疑问与解答&#xff1a; 1、俩动物以图片的形式显示&#xff1f; 其实在这里两个动物类就像标签一样 标签组件是什么&#xff1f;用于短文本字符串…

单链表经典算法LeetCode--203.移除链表元素(两种方法解)

1.链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;【点击即可跳转】 分析此题提供两种思路&#xff1a; 1.遍历原链表&#xff0c;将值为val的节点释放掉&#xff08;双指针法&#xff09; 定义一个pcur指针指向头节点&#xff0c;定义一个prev指针指向NULL 需要注…

【全开源】微凌客洗护小程序FastAdmin+Uniapp(源码搭建/上线/运营/售后/维护更新)

一款基于FastAdminUniapp开发的洗护小程序系统&#xff0c;适用于线上下单到店核销的业务场景&#xff0c;拥有会员卡、优惠券、充值提现、商户管理等功能&#xff0c;提供Uniapp后台无加密源代码。 线上线下融合&#xff1a;微凌客洗护小程序适用于线上下单到店核销的业务场景…

基于SpringBoot+Vue社区老人健康信息管理系统

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统社区老人健康信息管理系统信息管理难度大&#xff0c;容错…

Python-VBA函数之旅-staticmethod函数

目录 一、staticmethod函数的常见应用场景 二、staticmethod函数使用注意事项 三、如何用好staticmethod函数&#xff1f; 1、staticmethod函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a; https://blog…

鸿蒙开发-ArkTS语言-XML

鸿蒙开发-UI-web 鸿蒙开发-UI-web-页面 鸿蒙开发-ArkTS语言-基础类库 鸿蒙开发-ArkTS语言-并发 鸿蒙开发-ArkTS语言-并发-案例 鸿蒙开发-ArkTS语言-容器 鸿蒙开发-ArkTS语言-非线性容器 文章目录 前言 一、XML概述 二、XML生成 三、XML解析 1.解析XML标签和标签值 2.解析XML属性…

Matlab 验证 复数的幂计算规则

复数的幂计算规则 close all a9; b0:0.1:5;result1 exp(1j*2*pi*a.*b); result2 (exp(1j*2*pi*a)).^b; idxfind(result1result2); b_idxb(idx);figure plot(b,angle(result1(:)),-r*) hold on plot(b,angle(result2(:)),bo) grid on

QT如何增删安装的组件

打开 uninstall QT 往下会看到让你选择 add or remove component。 接下去就可以修改组件了