设为首页收藏本站

安徽论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 7714|回复: 0

Vue3如何理解ref toRef和toRefs的区别

[复制链接]

63

主题

501

回帖

950

积分

高级会员

Rank: 4

积分
950
发表于 2022-3-26 10:57:52 | 显示全部楼层 |阅读模式
网站内容均来自网络,本站只提供信息平台,如有侵权请联系删除,谢谢!
目录

Vue3中新增了几种创建响应式数据的方法,其各自的作用当然也不尽相同,每一种方法都有其自己的应用场景,今天我们来聊聊什么是ref toRef和toRefs?三者在使用方式上有什么不同?最佳的使用方式是什么?

一、基础



1.ref


(1) 生成值类型的响应式数据, 通过 .value修改值
  1. <template>
  2. <div>{{ ageRef }}</div>
  3. </template>

  4. <script>
  5. import { ref } from 'vue'
  6. export default {
  7. setup() {
  8.   const ageRef = ref(20)

  9.   setInterval(() => {
  10.    ageRef.value += 1
  11.   }, 1000)
  12.   
  13.   return {
  14.    ageRef
  15.   }
  16. },
  17. }
  18. </script>
复制代码
上面这段代码,定义了一个ageRef变量,并每秒将ageRef加1,页面展示的数值也会加1.

(2) 可用于reactive中

将上面的代码改动如下, 引入reactive定义变量,将ref定义的变量引入reactive中, 模板中展示reactive的变量. 最后的效果和上面(1)的一样
  1. <template>
  2. <div>{{ info.age }}</div>
  3. </template>

  4. <script>
  5. import { ref, reactive } from 'vue'
  6. export default {
  7. setup() {
  8.   const ageRef = ref(20)
  9.   const info = reactive({
  10.    age: ageRef
  11.   })
  12.   setInterval(() => {
  13.    ageRef.value += 1
  14.   }, 1000)
  15.   
  16.   return {
  17.    info
  18.   }
  19. },
  20. }
  21. </script>
复制代码
(3) 可用于获取Dom
  1. <template>
  2. <div ref="eleDom">ref-dom-test</div>
  3. </template>

  4. <script>
  5. import { ref, onMounted } from 'vue'
  6. export default {
  7. setup() {
  8.   const eleDom = ref(null)
  9.   onMounted(() => {
  10.    console.log(eleDom.value.innerHTML) // ref-dom-test
  11.   })
  12.   return {
  13.    eleDom
  14.   }
  15. },
  16. }
复制代码
上面代码控制台输出ref-dom-test, 说明获取到了Dom元素.
要获取Dom元素必须要符合以下规则
定义的ref变量名必须要和模板中ref中的值一致,如代码中的eleDom

2.toRef

       
  • 针对一个响应式对象的prop   
  • 创建一个ref,具有响应式   
  • 两者保持引用关系
我们来看下面这段代码
  1. <template>
  2. <div>{{ state.age }} --- {{ ageRef }}</div>
  3. </template>

  4. <script>
  5. import { toRef, reactive } from 'vue'
  6. export default {
  7. setup() {
  8.   const state = reactive({
  9.    name: 'JL',
  10.    age: 18
  11.   })
  12.   const ageRef = toRef(state, 'age')
  13.   setTimeout(() => {
  14.    state.age = 20
  15.   }, 1000)
  16.   
  17.   setTimeout(() => {
  18.    ageRef.value = 21
  19.   }, 2000)
  20.   
  21.   return {
  22.    state,
  23.    ageRef
  24.   }
  25. },
  26. }
  27. </script>
复制代码
上面的代码中,使用toRef将state的age属性变成一个响应式变量,然后在1秒后将state的age值变为20,此时ageRef也会变成20;在2秒后将ageRef的值变为21,此时state的age值也会变成21,说明了两者保持相互引用关系
toRef针对的是响应式,针对的不是普通对象,如果用于非响应式,产出的结果不具有响应式

3.toRefs

       
  • 将一个响应式对象转为普通对象   
  • 对象的每一个属性都是对应的ref   
  • 两者保持引用关系
我们来看下面这段代码
  1. <template>
  2. <div>{{ name }}---{{ age }}</div>
  3. </template>

  4. <script>
  5. import { reactive, toRefs } from 'vue'
  6. export default {
  7. setup() {
  8.   const state = reactive({
  9.    name: 'JL',
  10.    age: 18
  11.   })

  12.   const stateRefs = toRefs(state)

  13.   setTimeout(() => {
  14.    state.age = 20
  15.   }, 1000)

  16.   setTimeout(() => {
  17.    stateRefs.age.value = 21
  18.   }, 2000)

  19.   return stateRefs
  20. },
  21. }
  22. </script>
复制代码
上面的代码中,使用toRefs将state转变成一个普通对象,这时候就可以直接返回stateRefs,这时候在template就可以直接调用name和age。然后在1秒后将state的age值变为20,此时页面中的age也会变成20;在2秒后将stateRefs中的name的值变为21,此时页面中的age值也会变成21,说明了两者保持相互引用关系
toRefs将响应式对象变成普通对象后,每一个属性都具有响应式ref,此时需要使用 .value才能获取其值

4.最佳的使用方式

       
  • reactive做对象的响应式,ref做值类型响应式   
  • setup中返回toRefs(state), 或者toRef(state, 'xxx')---(这样就能够在template中不使用state.xxx)   
  • ref的变量命名都用xxxRef   
  • 合成函数返回响应式对象时,使用toRefs
例如:
  1. <template>
  2. <div>x:{{x}} y:{{y}}</div>
  3. </template>

  4. <script>
  5. import { reactive, toRefs } from 'vue'
  6. export default {
  7. setup() {
  8.   function test() {
  9.    const state = reactive({
  10.     x: 1,
  11.     y: 2
  12.    })
  13.    return toRefs(state)
  14.   }
  15.   const {x, y} = test()

  16.   setTimeout(() => {
  17.    x.value = 2
  18.   }, 1000)

  19.   return {
  20.    x,
  21.    y
  22.   }
  23. }
  24. }
  25. </script>
复制代码
上面的代码,test函数中定义了响应式对象state,并通过toRefs将其转为普通对象并返回,这时候可以结构赋值,并且值是响应式的


二、深入



1.为什么需要ref

在上面我们讲到,使用reactive和toRef也可以将值类型转换成响应式的,为什么还需要ref呢?
       
  • 值类型不具有响应式(proxy)   
  • setup()、computed()...都可能返回值类型,如果vue不定义ref,用户需要响应式的值类型的时候就会通过其他方式(reactive/toRef, reactive/toRefs)自造ref,就会造成代码更混乱

2.ref为什么需要.value

ref为什么需要加一个.value来获取值呢?为什么要这么麻烦呢?
       
  • ref是一个对象(不会丢失响应式),value存储值   
  • 通过.value属性的get和set来实现响应式   
  • 用于reactive和模板(vue编译)的时候不需要.value,其他情况都需要

3.为什么需要toRef和toRefs

       
  • 初衷: 在不丢失响应式的前提下,对对象数据进行解构   
  • 前提: 针对的是响应式对象,不是普通对象   
  • 结果: 不创造响应式,只延续响应式
到此这篇关于Vue3如何理解ref toRef和toRefs的区别的文章就介绍到这了,更多相关Vue3 ref toRef和toRefs内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
                                                        
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
免责声明
1. 本论坛所提供的信息均来自网络,本网站只提供平台服务,所有账号发表的言论与本网站无关。
2. 其他单位或个人在使用、转载或引用本文时,必须事先获得该帖子作者和本人的同意。
3. 本帖部分内容转载自其他媒体,但并不代表本人赞同其观点和对其真实性负责。
4. 如有侵权,请立即联系,本网站将及时删除相关内容。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表