ref 和 reactive (上)

5 阅读2分钟

这个问题面试几乎必问,但很多人讲不清。你记住一句话就够了:

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。


八、一张图总结(帮你记忆)

refvalue → .value → 响应式

reactive:
  object → Proxy → 直接访问

九、面试加分一句话(很关键)

👉 面试官如果深挖,你可以补一句:

Vue3 更推荐使用 ref,因为它在组合式 API 中更灵活,而且配合 script setup 使用时体验更好。


如果你愿意,我可以继续帮你补一波:

👉 ref vs reactive 面试“刁钻问题”(90%人会答错)
👉 或者出一道 Vue 响应式手写题(面试常见)