Vue 3 中的 toRefs 和 toRef:解构响应式对象的工具

举报
周杰伦本人 发表于 2025/01/22 14:20:50 2025/01/22
【摘要】 Vue 3 中的 toRefs 和 toRef:解构响应式对象的工具当我们使用 reactive 创建一个响应式对象时,直接解构对象的属性会导致失去响应式特性。这是因为解构出来的变量是普通的值,而不是响应式引用。这种问题该如何进行解决呢?这就要用到我们的toRefs 和 toRef解构响应式对象的工具了。在 Vue 3 中,toRefs 和 toRef 是两个非常有用的工具函数,用于从 re...

Vue 3 中的 toRefstoRef:解构响应式对象的工具

当我们使用 reactive 创建一个响应式对象时,直接解构对象的属性会导致失去响应式特性。这是因为解构出来的变量是普通的值,而不是响应式引用。这种问题该如何进行解决呢?这就要用到我们的toRefstoRef解构响应式对象的工具了。

在 Vue 3 中,toRefstoRef 是两个非常有用的工具函数,用于从 reactive 创建的响应式对象中解构属性,同时保持它们的响应式特性。接下来,我们将详细学习如何使用 toRefstoRef,并理解它们的作用和区别。

一、reactive 的解构问题

(一)问题描述

当我们使用 reactive 创建一个响应式对象时,直接解构对象的属性会导致失去响应式特性。这是因为解构出来的变量是普通的值,而不是响应式引用。

(二)示例代码

这是原始的代码

HTML复制

<template>
  <div>
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
  </div>
</template>

<script setup lang="ts">
import { reactive } from 'vue';

const person = reactive({
  name: '张三',
  age: 18
});

const changeName = () => {
  person.name = '张三波浪';
};

const changeAge = () => {
  person.age += 1;
};
</script>

这里修改person的属性,值会响应式的改变

(三)问题演示

如果直接解构 person

JavaScript复制

let { name, age } = person;

此时,nameage 是普通的值,而不是响应式的。修改它们不会影响 person,也不会触发视图更新。

二、toRefs 的作用

(一)toRefs 的定义

toRefs 是一个工具函数,用于将 reactive 创建的响应式对象中的每一组键值对转换为 ref,从而保持响应式特性。

(二)示例代码

HTML复制

<template>
  <div>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
  </div>
</template>

<script setup lang="ts">
import { reactive, toRefs } from 'vue';

const person = reactive({
  name: '张三',
  age: 18
});

const { name, age } = toRefs(person);

const changeName = () => {
  name.value = '张三波浪';
};

const changeAge = () => {
  age.value += 1;
};
</script>

(三)解释

  1. toRefs 的作用:将 reactive 创建的响应式对象中的每一组键值对转换为 ref

  2. 解构后的响应式:解构后的 nameageref 类型,通过 .value 访问和修改。

  3. 视图更新:修改 name.valueage.value 会触发视图更新。

三、toRef 的作用

(一)toRef 的定义

toRef 是一个工具函数,用于将 reactive 创建的响应式对象中的某个属性转换为 ref,从而保持响应式特性。

(二)示例代码

HTML复制

<template>
  <div>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
  </div>
</template>

<script setup lang="ts">
import { reactive, toRef } from 'vue';

const person = reactive({
  name: '张三',
  age: 18
});

const name = toRef(person, 'name');
const age = toRef(person, 'age');

const changeName = () => {
  name.value = '张三波浪';
};

const changeAge = () => {
  age.value += 1;
};
</script>

(三)解释

  1. toRef 的作用:将 reactive 创建的响应式对象中的某个属性转换为 ref

  2. 解构后的响应式:解构后的 nameageref 类型,通过 .value 访问和修改。

  3. 视图更新:修改 name.valueage.value 会触发视图更新。

四、toRefstoRef 的区别

(一)toRefs

  • 作用:将 reactive 对象中的所有属性转换为 ref

  • 使用场景:当你需要一次性解构多个属性时,使用 toRefs 更方便。

(二)toRef

  • 作用:将 reactive 对象中的某个属性转换为 ref

  • 使用场景:当你只需要解构单个属性时,使用 toRef 更灵活。

五、总结

(一)toRefstoRef 的用途

  • toRefs:将 reactive 对象中的所有属性转换为 ref,保持响应式特性。

  • toRef:将 reactive 对象中的某个属性转换为 ref,保持响应式特性。

(二)使用场景

  • toRefs:适用于一次性解构多个属性。

  • toRef:适用于解构单个属性。

(三)代码示例

HTML复制

<template>
  <div>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
  </div>
</template>

<script setup lang="ts">
import { reactive, toRefs, toRef } from 'vue';

const person = reactive({
  name: '张三',
  age: 18
});

// 使用 toRefs 解构所有属性
const { name, age } = toRefs(person);

// 或者使用 toRef 解构单个属性
const name = toRef(person, 'name');
const age = toRef(person, 'age');

const changeName = () => {
  name.value = '张三波浪';
};

const changeAge = () => {
  age.value += 1;
};
</script>

这就是Vue 3 中的 toRefstoRef的使用。在实际开发中,它们可以帮助你更灵活地解构响应式对象,同时保持响应式特性,避免因直接解构而导致的响应式丢失问题。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。