在 Vue 3 的组合式 API(Composition API)中,ref、reactive、toRef 和 toRefs 是四个非常重要的工具函数,用于创建和管理响应式数据。
一、ref
用ref()包裹数据,返回的响应式引用对象,包含一个 .value 属性,用于访问或修改值
typescript
import { ref } from 'vue';
const count = ref(0); // 创建一个响应式引用,初始值为 0
console.log(count.value); // 输出: 0
count.value++; // 修改值
console.log(count.value); // 输出: 1
二、reactive
reactive 用于创建一个响应式对象。它可以将一个普通对象转换为响应式对象,对象的所有属性都会变成响应式的。在访问值的时候,可直接用点的方式去访问,对比ref包裹的数据,后者需要.value才能访问到值
typescript
import { reactive } from 'vue';
const state = reactive({
name: 'Alice',
age: 25
});
console.log(state.name); // 输出: 'Alice'
state.age = 30; // 修改属性
console.log(state.age); // 输出: 30
三、toRef
toRef 用于从一个响应式对象中提取一个属性,并将其转换为一个响应式引用(ref)。它保持与原始对象的响应式连接,即使原始对象的属性值发生变化,toRef 创建的引用也会同步更新。
typescript
import { reactive, toRef } from 'vue';
const state = reactive({
name: 'Alice',
age: 25
});
const nameRef = toRef(state, 'name'); // 提取 `name` 属性并创建一个 ref
console.log(nameRef.value); // 输出: 'Alice'
state.name = 'Bob'; // 修改原始对象的属性
console.log(nameRef.value); // 输出: 'Bob'
nameRef.value = 'Charlie'; // 修改 ref 的值
console.log(state.name); // 输出: 'Charlie'
四、toRefs
toRefs 用于将一个响应式对象的所有属性转换为响应式引用(ref),并返回一个包含这些引用的普通对象。它通常用于解构响应式对象时,保持属性的响应式。
typescript
import { reactive, toRefs } from 'vue';
const state = reactive({
name: 'Alice',
age: 25
});
const { name, age } = toRefs(state); // 将所有属性转换为 ref
console.log(name.value); // 输出: 'Alice'
console.log(age.value); // 输出: 25
state.name = 'Bob'; // 修改原始对象的属性
console.log(name.value); // 输出: 'Bob'
name.value = 'Charlie'; // 修改 ref 的值
console.log(state.name); // 输出: 'Charlie'
五、补充
上文说到了,解构对象会失去响应式绑定,这里补充当使用展开运算符时出现的问题
typescript
import { reactive } from 'vue';
const a = reactive({ name: 'Alice', age: 25 });
const b = reactive({ ...a });
// 修改 a 中的属性
a.age = 30;
console.log(a); // { name: 'Alice', age: 30 }
console.log(b); // { name: 'Alice', age: 25 }
如果希望 b 中的属性与 a 中的属性保持同步,可以使用 toRefs 将 a 的属性转换为响应式引用,然后展开到 b 中。
typescript
import { reactive, toRefs } from 'vue';
const a = reactive({ name: 'Alice', age: 25 });
const b = { ...toRefs(a) };
// 修改 a 中的属性
a.age = 30;
console.log(a); // { name: 'Alice', age: 30 }
console.log(b); // { name: Ref< string > { value: 'Alice' }, age: Ref< number > { value: 30 } }