应使用 torefs() 或 toref() 解构组合式函数返回的响应式对象以保持响应性;直接解构会丢失响应性,导致视图不更新。

在 Vue 3 的组合式 API(Composition API)中,使用 setup() 或 defineComponent 时,常通过自定义组合式函数(Composable)封装逻辑。这些函数通常返回一个对象(如 { data, loading, fetch } ),而你可以用解构语法直接提取所需属性——但要注意响应性是否保留。
✅ 正确解构:用 toRefs() 保持响应性
组合式函数返回的通常是响应式对象(比如用 reactive() 或 ref() 创建的)。如果直接解构,会丢失响应性(即变成普通 JS 变量,修改它不会触发视图更新)。
解决方法:用 toRefs() 把响应式对象的每个属性转为独立的 ref,再解构:
import { toRefs } from 'vue'
import { useUser } from './composables/useUser'
export default {
setup() {
const { user, loading, fetchUser } = toRefs(useUser()) // ✅ 保持响应性
return { user, loading, fetchUser }
}
}
这样 user 和 loading 就是 Ref 类型,在模板中可直接用 {{ user.name }}(Vue 会自动解包);在 JS 中读取需 user.value,赋值需 user.value = {...}。
? 更简洁写法:用 toRef() 按需提取单个属性
如果你只关心对象中的某几个字段,又不想把整个对象都转成 ref,可以用 toRef() 单独“映射”:
import { toRef } from 'vue'
const { data } = useApi()
const items = toRef(data, 'items') // ✅ items 是 ref,且与 data.items 响应式联动
const count = toRef(data, 'count')
⚠️ 错误示范:直接解构会丢失响应性
下面这种写法看似简洁,但 不可取:
const { user, loading } = useUser() // ❌ user 和 loading 是普通变量,非响应式!
// 修改 user.name 不会触发更新,模板也不会重渲染
因为 useUser() 返回的是响应式对象,直接解构得到的是该对象属性的“快照”,脱离了响应式系统。
? 进阶技巧:配合解构重命名 + toRefs
支持别名解构,同时保持响应性:
const { user: currentUser, loading: isLoading } = toRefs(useUser())
// currentUser 和 isLoading 都是 Ref,可用在模板或逻辑中
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











