这个问题面试几乎必问,但很多人讲不清。你记住一句话就够了:
✅ ref 是“包一层盒子”
✅ reactive 是“直接改对象”
我用最通俗的方式帮你彻底搞懂👇
一、核心区别(先建立直觉)
✅ ref:包一层 .value
const count = ref(0);
count.value++; // 必须用 .value
👉 可以理解为:
count = {
value: 0
}
✅ reactive:直接操作对象
const state = reactive({
count: 0
});
state.count++; // 直接用
👉 没有 .value,更像普通对象
二、一句话区别总结(面试直接说)
ref 适合基本类型,也可以包对象;reactive 只适合对象类型,并且是深度响应式。
三、为什么要有 ref?(很多人答不出来🔥)
👉 因为:
❌ reactive 不能处理基本类型
const num = reactive(0); // ❌ 报错
👉 所以 Vue 提供了 ref 来解决这个问题
四、ref 和 reactive 的底层区别
ref 本质
function ref(value) {
return reactive({
value
});
}
👉 本质还是 reactive,只不过帮你包了一层 .value
reactive 本质
👉 基于 Proxy
const proxy = new Proxy(target, {
get() {},
set() {}
});
五、使用场景(重点🔥)
✅ 用 ref 的场景
1️⃣ 基本类型
const count = ref(0);
const name = ref('张三');
2️⃣ 单个变量(推荐)
const loading = ref(false);
const visible = ref(true);
👉 更清晰、更轻量
3️⃣ 需要解构(非常关键)
const count = ref(0);
return { count }; // 模板中不用 .value
✅ 用 reactive 的场景
1️⃣ 表单 / 对象
const form = reactive({
name: '',
age: 0
});
2️⃣ 多字段状态
const state = reactive({
loading: false,
list: [],
page: 1
});
六、常见坑(面试加分🔥)
🚨 1️⃣ reactive 不能直接解构
const state = reactive({ count: 0 });
const { count } = state; // ❌ 失去响应式
👉 解决:
import { toRefs } from 'vue';
const { count } = toRefs(state);
🚨 2️⃣ ref 包对象也可以
const user = ref({ name: '张三' });
user.value.name = '李四';
👉 但:
const user = reactive({ name: '张三' });
👉 更自然
🚨 3️⃣ template 中自动解包
<template>
{{ count }} <!-- 不用 .value -->
</template>
👉 Vue 自动帮你 .value
七、最佳实践(面试建议这样说🔥)
在 Vue3 中,我一般遵循:
- 基本类型 → 用 ref
- 单个状态 → 用 ref
- 复杂对象 / 表单 → 用 reactive
同时避免 reactive 解构丢失响应式的问题,如果需要解构会使用 toRefs。
八、一张图总结(帮你记忆)
ref:
value → .value → 响应式
reactive:
object → Proxy → 直接访问
九、面试加分一句话(很关键)
👉 面试官如果深挖,你可以补一句:
Vue3 更推荐使用 ref,因为它在组合式 API 中更灵活,而且配合 script setup 使用时体验更好。
如果你愿意,我可以继续帮你补一波:
👉 ref vs reactive 面试“刁钻问题”(90%人会答错)
👉 或者出一道 Vue 响应式手写题(面试常见)