ref是处理基础类型和确保响应式的首选方案,因reactive对基础类型静默失效、解构丢失响应式、重新赋值破坏代理,而ref天然支持所有场景且模板自动解包。

因为 ref 是唯一能安全包装基础类型(如 number、string、boolean)并保持响应式的方案,而 reactive 对基础类型直接无效——它不报错,但数据完全不会更新视图。
reactive 处理基础类型会静默失败
Vue3 的 reactive 内部基于 Proxy,而 Proxy 只能代理对象、数组、Map、Set 等引用类型。当你写:
let count = reactive(0)这段代码不会报错,但 count 就是一个普通数字,不是响应式对象。后续修改 count = 1,页面毫无反应,控制台也无提示——这是典型的“静默失效”,排查成本极高。
相比之下,ref(0) 明确返回一个带 .value 的响应式引用,类型安全、行为可预期。
解构 reactive 属性会丢失响应式
reactive 的响应式绑定在对象本身,而非变量名或属性路径。一旦你解构,就切断了与原始代理的连接:
- const { name, age } = reactive({ name: 'Alice', age: 25 }) → name 和 age 是普通值,修改它们不影响视图
- 想保留响应式?必须用 toRefs() 包一层,但每个属性又得加 .value,反而比 ref 更啰嗦
- 而 ref 的解构虽也不推荐,但至少 ref({}) 内部已转为 reactive,.value 始终指向响应式源
重新赋值 reactive 变量等于放弃响应式
常见错误场景:异步获取数据后直接替换整个对象
- state = await api.getData() → state 变量现在指向一个全新普通对象,原 reactive 代理被丢弃
- 正确做法是逐个赋值:state.id = res.id; state.name = res.name,或用 Object.assign(state, res)
- ref 则天然规避此问题:ref.value = 新对象,响应式链路始终完整
模板中 ref 自动解包,开发体验更一致
ref 在模板里无需 .value,和 Vue2 直观习惯一致;reactive 虽也不需要 .value,但一旦混用(比如从 API 拿到对象后想用 reactive 包装),就极易因类型判断失误导致响应失效。统一用 ref 处理所有初始值,逻辑更收敛、边界更清晰。










