Vue 3 中的响应式系统:ref 与 reactive 的对比与应用
Vue 3 的响应式系统是其核心特性之一,它允许开发者以声明式的方式构建用户界面。Vue 3 引入了两种主要的响应式 API:ref
和 reactive
。本文将详细介绍这两种 API 的用法、区别以及在修改对象属性和修改整个对象时的不同表现,并提供完整的代码示例。
1. ref 和 reactive 的定义
1.1 ref
ref
用于定义基本类型数据和对象类型数据。使用 ref
创建的变量必须通过 .value
属性访问和修改其值。
import { ref } from 'vue';
const count = ref(0); // 基本类型数据
const user = ref({ name: 'Alice', age: 20 }); // 对象类型数据
console.log(count.value); // 0
console.log(user.value.name); // Alice
1.2 reactive
reactive
用于定义对象类型数据。它返回一个响应式对象,可以直接访问和修改其属性,而不需要通过 .value
。
import { reactive } from 'vue';
const user = reactive({ name: 'Alice', age: 20 });
console.log(user.name); // Alice
2. ref 和 reactive 的区别
2.1 创建变量的方式
ref
创建的变量必须使用.value
访问。reactive
创建的对象可以直接访问其属性。
2.2 重新分配对象
reactive
重新分配一个新对象会失去响应式(可以使用Object.assign
去整体替换)。ref
可以通过.value
重新分配整个对象,且保持响应式。
3. 使用原则
3.1 基本类型数据
若需要一个基本类型的响应式数据,必须使用 ref
。
const count = ref(0);
3.2 对象类型数据
- 若需要一个响应式对象,层级不深,
ref
、reactive
都可以。 - 若需要一个响应式对象,且层级较深,推荐使用
reactive
。
const user = reactive({
name: 'Alice',
age: 20,
address: {
city: 'New York',
zip: '10001'
}
});
4. 修改对象属性和修改整个对象的区别
4.1 修改对象属性
当使用 reactive
创建响应式对象时,直接修改其属性会触发视图更新。
import { reactive } from 'vue';
const student = reactive({
name: 'Alice',
age: 20
});
student.name = 'Bob'; // 触发视图更新
student.age = 21; // 触发视图更新
4.2 修改整个对象
当使用 reactive
创建响应式对象时,重新分配一个新对象会失去响应式,需要使用 Object.assign
去整体替换。
import { reactive } from 'vue';
const student = reactive({
name: 'Alice',
age: 20
});
// 错误的做法,会失去响应式
student = { name: 'Bob', age: 21 };
// 正确的做法
Object.assign(student, { name: 'Bob', age: 21 }); // 触发视图更新
4.3 使用 ref 修改对象和属性
当使用 ref
创建响应式对象时,需要通过 .value
访问和修改其属性。
import { ref } from 'vue';
const studentRef = ref({
name: 'Alice',
age: 20
});
// 修改属性
studentRef.value.name = 'Bob'; // 触发视图更新
studentRef.value.age = 21; // 触发视图更新
// 修改整个对象
studentRef.value = { name: 'Charlie', age: 22 }; // 触发视图更新
5. 完整代码示例
以下是一个简单的 Vue 3 应用示例,展示了如何使用 ref
和 reactive
创建响应式数据,并演示了修改对象属性和修改整个对象的区别。
<template>
<div>
<p>Student (ref): {{ studentRef.value.name }}, {{ studentRef.value.age }}</p>
<button @click="updateStudentRef">Update Student (ref)</button>
<p>Student (reactive): {{ studentReactive.name }}, {{ studentReactive.age }}</p>
<button @click="updateStudentReactive">Update Student (reactive)</button>
</div>
</template>
<script>
import { ref, reactive } from 'vue';
export default {
setup() {
// 使用 ref 创建响应式数据
const studentRef = ref({
name: 'Alice',
age: 20
});
const updateStudentRef = () => {
studentRef.value.name = 'Bob';
studentRef.value.age = 21;
};
// 使用 reactive 创建响应式数据
const studentReactive = reactive({
name: 'Alice',
age: 20
});
const updateStudentReactive = () => {
studentReactive.name = 'Bob';
studentReactive.age = 21;
};
return {
studentRef,
updateStudentRef,
studentReactive,
updateStudentReactive
};
}
};
</script>
6. 总结
Vue 3 的 ref
和 reactive
提供了灵活的响应式数据管理方式。ref
适合基本类型数据和需要显式访问 .value
的场景,而 reactive
适合对象类型数据,特别是层级较深的对象。理解它们的区别和使用场景,可以帮助开发者更有效地构建响应式应用。
通过本文的介绍和示例代码,希望你能更好地理解 Vue 3 中的响应式系统,并在实际项目中灵活运用 ref
和 reactive
。