在Vue 3中,reactive
和ref
都是用于响应式数据的API。它们的主要区别在于使用方式和返回值类型。
reactive
:
reactive
函数用于将一个对象转换为响应式对象。它接收一个普通的JavaScript对象,并返回一个被代理的响应式对象。这意味着当响应式对象的属性发生更改时,Vue会自动检测到并重新渲染相关的组件。
import { reactive } from 'vue';
const state = reactive({
count: 0,
});
console.log(state.count); // 0
state.count = 5;
console.log(state.count); // 5
在上面的例子中,reactive
函数将一个普通的对象state
转换为响应式对象。我们可以直接访问响应式对象的属性,通过修改属性的值,Vue会自动更新相关的视图。
ref
:
ref
函数用于将一个值转换为响应式对象。它接收一个普通的JavaScript值,并返回一个包装的响应式对象,其值可以通过.value
进行访问和修改。
import { ref } from 'vue';
const count = ref(0);
console.log(count.value); // 0
count.value = 5;
console.log(count.value); // 5
在上面的例子中,ref
函数将一个数字0
转换为响应式对象。我们可以通过.value
来访问和修改响应式对象的值。
需要注意的是,在模板中使用ref
时,Vue会自动解包,你可以直接在模板中使用ref
对象,无需通过.value
属性访问其值。
总结:
- 使用
reactive
可以创建一个响应式的对象,访问和修改属性时不需要特殊处理。 - 使用
ref
可以创建一个响应式的包装对象,访问和修改值时需要使用.value
属性。
通常情况下,如果你需要创建一个包装的响应式对象,用于存储单个值,可以使用ref
。如果你需要创建一个包含多个属性的响应式对象,可以使用reactive
。
reactive() 的局限性
reactive() API 有两条限制:
- 仅对对象类型有效(对象、数组和 Map、Set 这样的集合类型),而对 string、number 和 boolean 这样的 原始类型
无效。 - 因为 Vue
的响应式系统是通过属性访问进行追踪的,因此我们必须始终保持对该响应式对象的相同引用。这意味着我们不可以随意地“替换”一个响应式对象,因为这将导致对初始引用的响应性连接丢失:
let state = reactive({ count: 0 })
// 上面的引用 ({ count: 0 }) 将不再被追踪(响应性连接已丢失!)
state = reactive({ count: 1 })