toRef与toRefs是Vue3中用于解构响应式对象的实用工具函数,主要解决reactive对象属性失去响应性的问题。 toRef针对单个属性转换,toRefs则批量处理对象属性。
toRef与toRefs的核心区别
-
toRef:将响应式对象(reactive对象)的单个属性转为独立的ref对象,保持与源属性的双向绑定关系(修改ref值会同步修改源对象)。
-
toRefs:将整个响应式对象的所有属性批量转换为普通对象,每个属性都是独立ref对象,常用于解构后保持响应性。
使用场景对比
- toRef适用场景:
- 需要单独操作某个深层嵌套属性时。
- 在组合式函数中返回特定属性给外部使用。
- toRefs适用场景:
- 解构reactive对象时保留所有属性的响应性。
- 在模板中直接展开对象属性避免冗余代码。
与reactive/ref的关联
1、与reactive的关系:
- toRef/toRefs必须基于reactive创建的响应式对象使用。
- 普通对象使用这两个API无法获得响应性。
2、与ref的差异:
- ref会拷贝数据并创建新引用,toRef/toRefs直接引用源数据。
- 修改ref值不会影响原始数据,而toRef的修改会同步到源对象。
toRef 示例:
<template>
<div>
<p>name: {{ name }}</p>
<p>age: {{ age }}</p>
<button @click="updateName">修改姓名</button>
<button @click="updateAge">修改年龄</button>
</div>
</template>
<script setup lang="ts">
import { reactive, toRef } from 'vue';
let person = reactive({ name: 'zs', age: 20 });
let name = toRef(person, 'name'); // 单个属性转ref
let age = toRef(person, 'age');
function updateName() {
name.value += '~~~'; // 修改ref值,同步更新person.name
};
function updateAge() {
age.value += 1; // 修改ref值,同步更新person.age
};
</script>
toRefs 示例:
<template>
<div>
<p>name: {{ name }}</p>
<p>age: {{ age }}</p>
<button @click="updateName">修改姓名</button>
<button @click="updateAge">修改年龄</button>
</div>
</template>
<script setup lang="ts">
import { reactive, toRefs } from 'vue';
let person = reactive({ name: 'zs', age: 20 });
// let name = toRef(person, 'name'); // 单个属性转ref
// let age = toRef(person, 'age');
const { name, age } = toRefs(person); // 批量转换所有属性
function updateName() {
name.value += '--'; // 修改ref值,同步更新person.name
};
function updateAge() {
age.value += 1; // 修改ref值,同步更新person.age
};
</script>