解构 reactive 对象会丢失响应性,应使用 toRefs 包裹后解构;对嵌套属性可用 toRef 精准绑定;或直接传递 reactive 引用;频繁整替数据时可改用 ref。

直接解构 reactive 对象会丢失响应性,因为解构出的是当前值的普通副本(比如数字、字符串),脱离了 Proxy 的拦截链路。要保留响应式联动,核心思路是:**不让解构操作拿到原始值,而是拿到能持续访问代理对象的“通道”**。
用 toRefs 包裹后再解构
这是最常用也最标准的解法。toRefs 把 reactive 对象的每个顶层属性都转成一个 ref,这些 ref 的 .value 内部仍通过 getter 访问原代理对象,因此修改它依然能触发更新。
- 必须先调用
toRefs(state),再解构:const { count, name } = toRefs(state) - 在
setup或组合式函数中,把解构结果直接返回,模板里可直接写{{ count }}(Vue 会自动解包 ref) - 在逻辑代码中读写需加
.value:count.value++ - 只作用于顶层属性;
state.user.name这类嵌套路径仍需手动处理,或改用computed+toRef
对深层字段用 toRef 单独绑定
当只需要响应式地使用某几个嵌套属性(比如 user.profile.avatar),又不想整个解构,可以用 toRef 精准绑定:
来自 Vercel Engineering 的 React 和 Next.js 性能优化指南。用于编写、审查或重构 React/Next.js 代码以确保最佳性
-
const avatar = toRef(user, 'profile.avatar')不合法 ——toRef只支持一级 key - 正确写法:
const avatar = toRef(user.profile, 'avatar')(前提是user.profile本身是 reactive 或 ref) - 适合表单子组件中局部编辑某个字段,且需要与父级保持双向同步的场景
避免解构,直接传 reactive 对象引用
如果子组件或工具函数只需读写对象属性,不强制要求解构变量名,最简单的方式就是不拆:
- 父组件传
:user="userInfo",子组件接收const { user } = defineProps({ user: Object }) - 子组件内始终用
user.name、user.age访问 —— 因为user是 proxy 引用,所有属性访问仍走拦截器 - 比 toRefs 更轻量,无额外 ref 封装开销,适用于不需要重命名或逻辑隔离的场景
用 ref 包裹对象替代 reactive
如果业务中频繁需要解构 + 重新赋值整个对象(比如接口刷新后替换全部数据),用 ref 更稳妥:
const user = ref({ name: 'Alice', age: 25 })- 更新整条数据:
user.value = newData,响应性不丢失(ref 的 setter 内部会调用toReactive) - 解构时仍需注意:
const { name } = user.value会丢响应性;正确做法是const name = computed({ get: () => user.value.name, set: v => user.value.name = v }) - 适合数据整体替换频繁、结构相对固定、且对性能不敏感的模块
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









