Vue3响应式函数toRef()对比toRefs()源码分析

其他教程   发布日期:2023年09月03日   浏览次数:397

今天小编给大家分享一下Vue3响应式函数toRef()对比toRefs()源码分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

  1. ref
是处理基本数据类型响应式
  1. API
函数,在
  1. setup
中声明定义的变量,可以直接在模板中使用

没有被响应式

  1. API
包裹处理的变量数据,是不具备响应式能力的

也就是往往在逻辑中修改了数据,但是页面不会更新,那怎么样将一个非响应式数据变成响应式数据

就需要用到

  1. toRef()
  1. toRefs()
这两个
  1. componsition API

单纯的去看概念,往往比较抽象,是难以理解的,还是需要从具体的实例出发

toRef()函数

作用:创建一个

  1. ref
对象,其
  1. value
值指向另一个对象中的某个属性值,与原对象是存在关联关系的。

也就是基于响应式对象上的一个属性,创建一个对应的

  1. ref
,这样创建的
  1. ref
与它的源属性是保持同步的,与源对象存在引用关系

改变源属性的值将更新

  1. ref
的值

语法:

  1. const
变量名 =
  1. toRef(源对象,源对象下的某个属性)

如:

  1. const name = toRef(person,'name')

应用: 要将响应式对象中的某个属性单独提供给外部使用时,不想丢失响应式,把一个

  1. prop
  1. ref
传递给一个组合式函数也会很有用

缺点

  1. toRef()
只能处理一个属性,但是
  1. toRefs(源对象)
,却可以一次性批量处理

  1. <script setup>
  2. import { reactive } from "vue";
  3. const person = reactive({
  4. name:"川川",
  5. age: 18,
  6. job: {
  7. web: '前端开发',
  8. trade: '互联网'
  9. }
  10. });
  11. </script>

那在模板当中想要渲染数据可以这么写

  1. {{person.name}} -{{person.age}}-{{person.job.web}}-{{person.job.trade}}

如果不想在模板当中,写那么长,那么可以先解构,如下所示

  1. <script setup>
  2. import { reactive } from "vue";
  3. const person = reactive({
  4. name:"川川",
  5. age: 18,
  6. job: {
  7. web: '前端开发',
  8. trade: '互联网'
  9. }
  10. });
  11. const { name, age} = person;
  12. const { web,trade} = person.job;
  13. </script>

那在模板中,可以直接使用变量的,如下所示

  1. {{name}}-{{age}}-{{web}}-{{trade}}

现在,如果我们想要去修改变量数据,会发现,逻辑中的数据会被修改,但是页面中的数据不会更新,也就是丢失了响应式 比如:如下模板,分别修改名字,年龄属性

  1. <button @click="handleChangeAttrs">修改属性</button>

那在逻辑代码中

  1. <script setup>
  2. import { reactive } from "vue";
  3. const person = reactive({
  4. name:"川川",
  5. age: 18,
  6. job: {
  7. web: '前端开发',
  8. trade: '互联网'
  9. }
  10. });
  11. const { name, age} = person;
  12. const { web,trade} = person.job;
  13. // 这样直接操作数据是无法修改的,因为它不是一个响应式数据,只是一个纯字符串,不具备响应式
  14. function handleChangeAttrs() {
  15. name = "itclanCoder";
  16. age = 20;
  17. }
  18. </script>

如果想要修改数据,支持响应式,将一个非响应式数据,变成一个响应式数据,需要借用

  1. toRef(源对象,源对象下指定的属性)函数
,如下所示

  1. <script setup>
  2. import { reactive,toRef } from "vue";
  3. const person = reactive({
  4. name:"川川",
  5. age: 18,
  6. job: {
  7. web: '前端开发',
  8. trade: '互联网'
  9. }
  10. });
  11. // 想要修改指定哪个对象具备响应式,那么就使用toRef函数处理,toRef(源对象,源对象下的某个属性)
  12. const name = toRef(person'name');
  13. const age = toRef(person,'age');
  14. // 经过了toRef的处理,修改变量的值,那么就需要xx.value
  15. function handleChangeAttrs() {
  16. name.value = "itclanCoder";
  17. age.value = 20;
  18. }
  19. </script>

在模板当中,仍然是如上所示

  1. {{person}}
  2. {{name}}-{{age}}-{{web}}-{{trade}}
  3. <button @click="handleChangeAttrs">修改属性</button>

你会发现使用

  1. toRef()
函数处理后,非响应式数据就具备响应式数据的能力了的,而且源数据也会同步

如果只是用于纯数据页面的展示,那是没有必要将数据转化为响应式数据的,如果需要修改数据,那么就需要将非响应式数据转化为响应式数据

是通过

  1. toRef()
函数实现的

与ref的不同

如果你用

  1. ref
处理数据的话,如下所示,使用
  1. ref
处理数据,页面也能实现数据的响应式,更新,但是它与
  1. toRef
是不同,有区别的

  1. <script setup>
  2. import { reactive,toRef } from "vue";
  3. const person = reactive({
  4. name:"川川",
  5. age: 18,
  6. job: {
  7. web: '前端开发',
  8. trade: '互联网'
  9. }
  10. });
  11. // 使用ref
  12. const name = ref(person.name);
  13. const age = toRef(person.age);
  14. // 经过了toRef的处理,修改变量的值,那么就需要xx.value
  15. function handleChangeAttrs() {
  16. name.value = "itclanCoder";
  17. age.value = 20;
  18. }
  19. </script>

修改数据,页面数据会更新,但是源数据不会同步,修改,并无引用关系,

  1. ref
相当于是对源对象重新拷贝一份数据
  1. ref()
接收到的是一个纯数值

toRefs()函数

  1. toRef()
只能处理源对象指定的某个属性,如果源对象属性很多,一个一个的使用
  1. toRef()
处理会显得比较麻烦

那么这个

  1. toRefs()
就很有用了,它与
  1. toRef()
的功能一致,可以批量创建多个
  1. ref
对象,并且能与源对象保持同步,有引用关系

语法:

  1. toRefs(源对象)
,
  1. toRefs(person)

如上面的示例代码,修改为

  1. toRefs()
所示

  1. <script setup>
  2. import { reactive,toRefs } from "vue";
  3. const person = reactive({
  4. name:"川川",
  5. age: 18,
  6. job: {
  7. web: '前端开发',
  8. trade: '互联网'
  9. }
  10. });
  11. // 通过toRefs()批量处理,此时通过解构
  12. const {name,age} = toRefs(person);
  13. // 经过了toRef的处理,修改变量的值,那么就需要xx.value
  14. function handleChangeAttrs() {
  15. name.value = "itclanCoder";
  16. age.value = 20;
  17. }
  18. </script>

当从组合式函数中返回响应式对象时,

  1. toRefs
是很有用的。使用它,消费者组件可以解构/展开返回的对象而不会失去响应性

  1. import { toRefs } from "vue";
  2. function useFeatureX() {
  3. const state = reactive({
  4. foo: 1,
  5. bar: 2
  6. })
  7. // 在返回时都转为ref
  8. return toRefs(state)
  9. }
  10. // 可以解构而不会失去响应性
  11. const { foo, bar } = useFeatureX()

注意事项

  1. toRefs
在调用时只会为源对象上可以枚举的属性创建
  1. ref
。如果要为可能还不存在的属性创建
  1. ref
,则改用
  1. toRef

为啥需要toRef()与toRefs()函数

目的:在保证不丢失响应式的前提下,把对象进行解构,方便对象数据分解和扩散

前提:针对的是响应式对象(

  1. reactive
封装的)非普通对象

注意:不创造响应式(那是

  1. reactive
的事情),它本身只是延续响应式,让一个非响应式数据通过
  1. toRef
  1. toRefs
转换为响应式数据能力

以上就是Vue3响应式函数toRef()对比toRefs()源码分析的详细内容,更多关于Vue3响应式函数toRef()对比toRefs()源码分析的资料请关注九品源码其它相关文章!