在 Vue 3 中,ref 和 reactive 都是用来创建响应式数据的核心 API,但它们的使用场景和行为有明显区别。
下面我给你一个对比总结 + 示例代码,方便你快速理解和选择。
1. 基本区别
| 特性 | ref | reactive |
|---|---|---|
| 数据类型 | 适合基本类型(number、string、boolean 等),也可包裹对象 | 适合对象类型(对象、数组、Map、Set 等) |
| 访问方式 | 在 JS 中需要 .value 访问/修改值(模板中会自动解包) | 直接访问属性即可 |
| 深度响应 | 对象类型会被自动转成 reactive(深度响应) | 默认深度响应 |
| 解包行为 | 模板中自动解包,JS 中必须 .value | 无需 .value |
| 替换整个值 | 直接 myRef.value = newValue | 必须替换整个对象引用才能触发(浅层属性修改会触发) |
2. 示例代码
<script setup>
import { ref, reactive } from 'vue'
// 1. ref 适合基本类型
const count = ref(0)
function increment() {
count.value++
}
// 2. reactive 适合对象
const user = reactive({
name: 'Alice',
age: 25
})
function birthday() {
user.age++
}
// 3. ref 也可以包裹对象(内部会转 reactive)
const settings = ref({
theme: 'dark',
lang: 'en'
})
function changeTheme() {
settings.value.theme = 'light' // 依然是响应式的
}
</script>
<template>
<div>
<h3>ref 基本类型</h3>
<p>Count: {{ count }}</p>
<button @click="increment">+1</button>
<h3>reactive 对象</h3>
<p>{{ user.name }} - {{ user.age }}</p>
<button @click="birthday">过生日</button>
<h3>ref 包裹对象</h3>
<p>Theme: {{ settings.theme }}</p>
<button @click="changeTheme">切换主题</button>
</div>
</template>
3. 选择建议(最佳实践)
- 基本类型 → 用
ref(更直观,避免多余 Proxy 包装)。 - 对象/数组 → 用
reactive(直接访问属性,无需.value)。 - 如果需要整体替换对象,
ref包裹对象更方便(settings.value = newObj)。 - 在组合式 API 中,
ref更适合跨组件传递单值状态,reactive更适合管理复杂状态对象。
✅ 记忆口诀:
"单值用 ref,结构用 reactive;要替换用 ref,要修改用 reactive"