Vue 3 中 ref 数据必须通过 .value 修改,否则视图不更新;ref 是 RefImpl 实例,仅 .value 属性被响应式系统监听,直接赋值或提前解构会丢失响应性。

Vue 3 中用 ref 创建的数据,必须通过 .value 修改,否则视图不会更新——这不是 bug,而是响应式机制的硬性要求。
修改 ref 数据必须走 .value 链路
ref 包裹的是一个对象(RefImpl 实例),真正存储值的是它的 .value 属性。Vue 的响应式系统只监听这个属性的变化。
- ✅ 正确写法:
count.value++、user.value.name = '李四'、flag.value = false - ❌ 错误写法:
count = 10(直接赋值,ref 实例被覆盖)、const u = user.value; u.name = '王五'(脱离响应链)
嵌套对象和数组更新也得经过 .value
即使 ref 里存的是对象或数组,所有读写操作仍要从 .value 开始,否则 Vue 无法追踪。
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
- 对象新增字段:
form.value.profile.city = '杭州'✅(响应式新增支持) - 数组原地修改:
list.value.push(item)或list.value.splice(0, 1)✅ - 数组整体替换:
list.value = newList✅(替换内容,不换 ref 壳) - ⚠️ 错误示例:
list = list.value.filter(...)❌(漏了 .value,等于重赋 ref 变量)
传给子组件或 store 时别提前解构
一旦把 .value 的结果传出去,就变成普通 JS 值,响应性立刻中断。
立即学习“前端免费学习笔记(深入)”;
- ✅ 推荐暴露方式:
return { user, count }(传 ref 实例本身) - ✅ 解构保持响应:
return { ...toRefs(store) }(toRefs 会为每个属性生成带响应的 ref) - ❌ 危险操作:
const { name } = user; return { name }(解构即失联) - ❌ 子组件接收:
defineProps({ name: String })并传入user.value.name—— 普通字符串,不响应
调试确认响应性是否还在
遇到视图不更新,先验证 ref 是否还“活着”:
- 打印
console.log(user):看到RefImpl { value: {...} }才正常 - 检查
isReactive(user.value):应返回true(对对象)或false(对基本类型,但 ref 本身是响应式) - 避免在 setup 里写
let u = user.value后再改u.xxx,这等于断开了 Vue 的追踪路径

















