在 Vue 3 中,ref 和 reactive 都是用于创建响应式数据的核心 API,但它们的使用场景、语法习惯和适用数据类型有所不同。以下是清晰的对比与使用建议:
✅ 什么时候用 ref?
适用场景:
-
处理基本数据类型(如
number、string、boolean)因为
reactive只能包装对象/数组,不能直接包装基本类型。 -
需要整体替换变量值
比如从接口重新获取一个新值并赋给变量:
count.value = newData,仍保持响应性。 -
获取 DOM 元素或组件实例(模板引用)
<input ref="inputEl" />const inputEl = ref(null) // inputEl.value 就是 DOM 元素 -
在
<script setup>中更方便地导出或传递简单状态ref是“容器”,天然适合在函数间传递而不丢失响应性。
示例:
const count = ref(0)
const loading = ref(true)
const title = ref('Hello')
在模板中直接写
{{ count }},Vue 会自动.value解包。
✅ 什么时候用 reactive?
适用场景:
-
处理复杂对象或嵌套结构(如用户信息、表单状态、配置对象)
避免写一堆
.value,代码更简洁。 -
多个相关属性需要一起管理
比如一个表单包含 name、email、age 等字段。
-
频繁操作对象内部属性(增删改嵌套属性)
直接
user.name = 'xxx',无需.value。
示例:
const user = reactive({
name: 'Alice',
age: 25,
address: {
city: 'Beijing'
}
})
// 修改:user.age++ ✅ 直接操作
⚠️ 注意:不能整体替换
reactive对象(如user = newUser会丢失响应性)。
🔍 核心区别速查表
| 特性 | ref | reactive |
|---|---|---|
| 适用类型 | 所有类型(尤其基本类型) | 仅对象/数组 |
| 访问方式(JS中) | ref.value | 直接 obj.prop |
| 模板中使用 | 自动解包(写 count 即可) | 直接使用 |
| 整体替换 | ✅ 支持(count.value = 100) | ❌ 替换后失去响应性 |
| 解构是否保持响应性 | 是(本身是引用) | 否(需用 toRefs) |
| 底层实现 | 内部用 reactive({ value: xxx }) 包装 | 基于 Proxy |
🛠 最佳实践建议
-
简单状态(计数器、开关、文本) → 用
ref -
复杂状态(对象、表单、配置) → 用
reactive -
混合场景:可以同时用!例如:
const form = reactive({ name: '', email: '' }) const submitting = ref(false) const inputRef = ref(null) -
需要解构
reactive对象? → 用toRefs(form)保持响应性。
💡 总结一句话:
用
ref管“值”,用reactive管“对象”。
只要记住这一点,就能在绝大多数场景下做出正确选择。