从0开始vue3(四) | toRef和toRefs

2,101 阅读3分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。

vue3慢慢学系列!🙉

前言

首先我们先来回顾一下上期说到的ref和reactive,一般来说,

  • ref用来定义简单的字符串或者数值的响应式,
  • reactive用来定义对象数组的响应式。

toRef的定义

这期我们先从toRef开始看起,官网上它的定义是这样的:

📖 toRef

可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。

光看这句话是不是有点不知道是什么意思,下面我们就来分析一下这句话。

首先从定义中可以看出,toRef针对的是一个响应式对象的prop。那我们先来创建一个响应式的对象。(前面说过,创建对象的响应式,我们应该使用reactive。)

 let obj = reactive({count: 3});

那这有什么问题呢?我们先来测一个很普通的写法

image-20220201205124987

我们对【对象】的属性值进行动态的改变,从效果图可以看到,一切看起来都很正常。(不论是视图上还是控制台里值都正常更新)

那现在我们来对以上的代码做一点点的改动,把对象属性的值先赋给一个变量,在进行操作。

image-20220201212509251

这个时候,再来看运行效果会发现,问题出现了,除了我们新赋值的变量值有改变之外,视图和原值都没有更新。

toRef的作用

而toRef就是来解决以上的问题,上面的问题很明显是我们的响应断了,从开头toRef的定义中可以看到,toRef会保持对其源 property 的响应式连接

现在我们就加上toRef来看看

<script setup>
   import {reactive,toRef} from 'vue'
   let obj = reactive({count: 3});
   let currentCountRef = toRef(obj,'count') //第一个参数是对象,第二个参数是属性名
   function add1() {
     currentCountRef.value++
     console.log('obj的值:', obj);
     console.log('currentCountRef的值:', currentCountRef);
   }
</script>

这个时候再看,不论是视图,原值,还是赋值的变量值都有保持实时更新。

ref和toRef

toRef的定义中说:可以用来为源响应式对象上的某个 property 新创建一个 ref。那我们直接用ref行不行,可以来试试

image-20220201214108417

🎨 运行效果:可以看到,如果使用ref,只是让赋值的变量自己保持了响应,但是原来的对象值不会改变。

ref和toRef的区别

reftoRef
ref接收一个参数:ref(原始值)toRef接收两个参数:toRef(Proxy, 'xxprop')
本质是拷贝,修改响应式数据不会影响原始数据本质是引用关系,修改响应式数据会影响原始数据

toRefs

官网上的定义:

将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。

可以看到toRefs和toRef很像,从名字上他们长的差不多,从作用看他们确实也是差不多。只不过一个是对【对象】属性单个处理,一个是进行批量处理。

<script setup>
  import {reactive,toRefs} from 'vue'
  let obj = reactive({
    name: '张三',
    age:18
  });
  
  let name = toRef(obj,'name')
  let age = toRef(obj,'age')
  //等价于
  let {name,age} = toRefs(obj)
  
</script>

其他:

toRefs的一大用途就是变相解构Proxy,首先了解一个常识,Proxy如果解构,基本数据会丢失响应式。

import { reactive } from 'vue'

let obj = reactive({
    name: '张三',
    age:18
  });

let { name, age } = obj;
/*如果直接这样写,这两个 property 的响应性都会丢失。对于这种情况,我们需要将我们的响应式对象转换为一组 ref。这些 ref 将保留与源对象的响应式关联*/

所以如果,既想要解构Proxy,又不想丢失响应式,就可以使用toRefs。

结尾

欢迎勘误💥

参考资料:

响应性API toRef

响应性API toRefs

响应性基础


🎨【点赞】【关注】不迷路,更多前端干货等你解锁

往期推荐

👉 JavaScript的Proxy代理怎么用?

👉 JS中的getter和setter你会用吗?

👉 深入理解ES6箭头对象

👉 JS的装饰器模式实例分析