直接解构 reactive 对象会失效,因为解构出的变量是普通值或原始引用,脱离 proxy 拦截;torefs 可将每个属性转为 ref 保持响应式,读写需 .value;模板中推荐直接访问 state.xxx 或 props.xxx。

直接解构 reactive 对象为什么会失效
reactive 返回的是一个 Proxy 代理对象,它的响应式能力依赖于对这个代理的属性访问。一旦你写 const { count } = state,JavaScript 就会执行一次读取操作,把 state.count 当前的值(比如数字 0)拷贝出来,赋给局部变量 count。这个 count 是普通数值,不再经过 Proxy 的 get/set 拦截,Vue 也收不到它的变化通知。
对嵌套对象也一样:如果 state.user 是个响应式子对象,const { user } = state 得到的 user 是原始对象引用,不是代理对象,后续改 user.name 不会触发更新。
用 toRefs 保持解构后的响应式
toRefs 的作用是把 reactive 对象的每个属性都转成独立的 ref,每个 ref 内部仍指向原对象的对应属性,从而维持响应链不中断。
- 写法:const { count, name } = toRefs(state)
- 模板中可直接写
{{ count }}(Vue 会自动解包 .value) - 逻辑中读写需加
.value:如count.value++或name.value = 'Bob'
不依赖解构的更稳妥写法
如果只是想在模板或计算中使用,完全没必要解构:
- 模板里直接写
{{ state.count }}或{{ state.user.name }} - 需要派生数据时,用
computed(() => state.count * 2),依赖能正常追踪 - 组合式函数返回 reactive 对象时,调用方也应避免解构,改用
const store = useStore(),再通过store.count访问
父组件传 props 给子组件也要注意
子组件 setup 中写 const { title } = props 同样会丢失响应式——因为 props 是只读代理,解构后得到的是快照值。
- 正确方式一:始终通过
props.title访问 - 正确方式二:用
const { title } = toRefs(props),之后title.value可响应 - 模板中推荐直接写
{{ props.title }},最简洁且零风险










