概述
storeToRefs 是专门用来把 Pinia store 解构成「仍然有响应性 + 完整 TS 提示」的 refs 工具。
一、storeToRefs 是干嘛的?
问题背景
ts
const store = useUserStore()
const { name } = store // ❌ 响应性断了 + TS 变弱
解决方案
ts
import { storeToRefs } from 'pinia'
const store = useUserStore()
const { name } = storeToRefs(store) // ✅
结果:
name是Ref<string>- 响应性不丢
- TS 自动补全、类型检查完整
二、它到底"帮你做了什么"?
storeToRefs(store) 会:
-
只处理
stategetters
-
跳过
actions
-
把它们统一包成
ref / computed
可以把它理解成:
ts
// 伪代码
{
stateKey: toRef(store, 'stateKey'),
getterKey: computed(() => store.getterKey),
}
三、TS 类型长什么样?
Store 定义
ts
export const useUserStore = defineStore('user', {
state: () => ({
name: 'Tom',
age: 18,
}),
getters: {
isAdult: (state) => state.age >= 18,
},
actions: {
setName(name: string) {
this.name = name
},
},
})
使用 storeToRefs
ts
const store = useUserStore()
const { name, age, isAdult } = storeToRefs(store)
TS 推导结果
ts
name // Ref<string>
age // Ref<number>
isAdult // ComputedRef<boolean>
✔ 不会是 any ✔ 不会丢 getter 类型 ✔ 自动区分 Ref / ComputedRef
四、为什么 actions 不能放进去?
ts
const { setName } = storeToRefs(store) // ❌ 不存在
因为:
- action 是普通函数
- 不需要响应性
- 包成 ref 反而会破坏
this/ 调用方式
👉 正确做法:
ts
const { setName } = store
五、最标准、最推荐的组合写法
ts
const store = useUserStore()
const { name, age, isAdult } = storeToRefs(store)
const { setName } = store
这是 Pinia 官方文档 + 实战 都默认的模式。
六、模板里为什么不用 .value?
ts
<script setup lang="ts">
const store = useUserStore()
const { name } = storeToRefs(store)
</script>
<template>
{{ name }} <!-- 自动 unref -->
</template>
- Vue template 会自动
unref - TS 仍然认为它是
Ref<string> - 两边都正确 ✅
七、什么时候一定要用 storeToRefs?
✅ 必须用
- 在
setup()/script setup里解构 store - 想保留响应性 + TS 提示
- 把 store 拆开传给 composable
❌ 不用
store.name store.isAdult store.setName()
不解构 = 不需要
storeToRefs
八、总结
Pinia 解构三原则
- 解构
state / getters👉storeToRefs- 解构
actions👉 直接解- 能不解构就不解构(TS 最稳)