《Vue3 从入门到大神06篇》ref 还是 reactive?一文搞懂响应式数据的选择

📅 2026/6/18 4:50:02
《Vue3 从入门到大神06篇》ref 还是 reactive?一文搞懂响应式数据的选择
在 Vue3 中我们拥有了两个创建响应式数据的 APIrefreactive于是几乎所有初学者都会遇到同一个问题❓什么时候用 ref什么时候用 reactive​❓为什么 ref 要写.value​❓为什么解构会丢失响应式这篇文章我们就来一次把这些疑问彻底讲清楚。一、一句话结论先给你答案数据类型推荐 API基本类型string / number / boolean✅ref对象 / 数组✅reactive或ref表单字段 / 单个状态✅ref复杂状态对象✅reactive经验法则能用 ref 解决的就用 ref复杂对象再用 reactive。二、ref为基本类型而生1️⃣ ref 的基本用法import { ref } from vue const count ref(0) count.value console.log(count.value) // 12️⃣ 为什么 ref 需要.value因为JavaScript 的基本类型不是对象不能被 Proxy 直接代理。Vue3 的解决方案是ref(0) → { value: 0 }ref 本质用一个对象包裹基本类型对这个对象的value做响应式处理三、reactive为引用类型而生1️⃣ reactive 的基本用法import { reactive } from vue const state reactive({ count: 0, user: { name: Tom } })2️⃣ 使用方式state.count state.user.name Jerry✅不需要.value​✅可以直接访问属性四、ref 和 reactive 的本质区别对比项refreactive包装方式{ value }Proxy支持类型基本 引用仅引用.value必须不需要替换整个对象✅ 支持❌ 丢失响应式解构❌ 易丢响应式✅ 可直接解构五、.value的底层原理面试重点1️⃣ ref 的简化实现function ref(value) { const wrapper { value } return reactive(wrapper) }核心思想ref内部其实也用了reactive只是多包了一层value六、解构为什么会丢失响应式非常重要1️⃣ 错误示例const state reactive({ count: 0 }) const { count } state count // ❌ 不再是响应式2️⃣ 原因图解state.count → Proxy count → 普通数字脱离 Proxy结论解构得到的是“值本身”不是“代理引用”。七、如何正确解构响应式数据✅ 方案 1toRefsimport { reactive, toRefs } from vue const state reactive({ count: 0 }) const { count } toRefs(state) count.value✅ 方案 2保持 state 不变state.count八、ref 和 reactive 的常见误区❌ 误区 1reactive 可以替换 refconst count reactive({ value: 0 }) // ❌ 不推荐原因语义混乱不符合 Vue 设计初衷。❌ 误区 2ref 不能包对象const user ref({ name: Tom })✅这是允许的但注意user.value.name Jerry九、实战选择建议强烈建议收藏✅ 表单场景const username ref() const password ref()✅ 复杂业务对象const user reactive({ id: 1, name: , roles: [] })✅ 组合式函数返回function useCounter() { const count ref(0) const inc () count.value return { count, inc } }十、面试高频问答Q1ref 为什么要.value因为基本类型不能被 Proxy 代理需要包一层对象。Q2reactive 解构为什么会失效解构得到的是原始值脱离了 Proxy。Q3什么时候用toRefs当你需要把 reactive 拆成多个 ref 使用时。十一、总结ref基本类型 单个状态reactive复杂对象.value是 ref 的设计必然解构 reactive 会丢失响应式toRefs是解决手段 下期预告第 07 篇计算属性与侦听器 —— computed 与 watch 的高级玩法