浅谈 storeToRefs

概述

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) // ✅

结果:

  • nameRef<string>
  • 响应性不丢
  • TS 自动补全、类型检查完整

二、它到底"帮你做了什么"?

storeToRefs(store) 会:

  1. 只处理

    1. state
    2. getters
  2. 跳过

    1. actions
  3. 把它们统一包成 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 最稳)
相关推荐
失忆爆表症4 小时前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
小迷糊的学习记录4 小时前
Vuex 与 pinia
前端·javascript·vue.js
发现一只大呆瓜4 小时前
前端性能优化:图片懒加载的三种手写方案
前端·javascript·面试
不爱吃糖的程序媛4 小时前
Flutter 与 OpenHarmony 通信:Flutter Channel 使用指南
前端·javascript·flutter
利刃大大4 小时前
【Vue】Element-Plus快速入门 && Form && Card && Table && Tree && Dialog && Menu
前端·javascript·vue.js·element-plus
NEXT064 小时前
AI 应用工程化实战:使用 LangChain.js 编排 DeepSeek 复杂工作流
前端·javascript·langchain
念风零壹4 小时前
AI 时代的前端技术:从系统编程到 JavaScript/TypeScript
前端·ai
光影少年5 小时前
react的hooks防抖和节流是怎样做的
前端·javascript·react.js
小毛驴8505 小时前
Vue 路由示例
前端·javascript·vue.js
发现一只大呆瓜6 小时前
AI流式交互:SSE与WebSocket技术选型
前端·javascript·面试