跳转到主内容
极星编程网:以代码为星,赴技术山海!

Pinia 组合式 API 怎么写?教你像写 Setup 一样编写全局状态的技巧

Pinia组合式API本质是将setup逻辑移入store,用defineStore返回含ref/computed/function的标准Composition API函数,支持类型标注、逻辑复用及生命周期钩子。 Pinia 的组合式 API 写法,核心就是用
defineStore
配合箭头函数 +
ref
/
computed
/
function
来组织状态逻辑,和组件里的
setup()
风格高度一致——不是“像写 Setup”,它本来就是用 Setup 的思维写的。 定义 store 就是写一个带返回值的 setup 函数 不用 class、不写 options,直接导出一个函数,里面声明响应式数据、计算属性、方法,最后 return 出去:
import { defineStore } from 'pinia' import { ref, computed } from 'vue' export const useUserStore = defineStore('user', () => { // 状态 const name = ref('张三') const age = ref(25) // 衍生状态(computed) const isAdult = computed(() => age.value >= 18) // 方法 function updateName(newName) { name.value = newName } function grow() { age.value++ } // 必须 return!暴露给组件用 return { name, age, isAdult, updateName, grow } })
这个函数体内部,就是标准的 Composition API 写法,支持
ref
、
computed
、
watch
、
onMounted
(需配合
onActivated
等生命周期钩子)等所有 setup 能用的能力。 需要 TS 类型?直接在 return 上加类型标注 不需要额外 interface 或泛型包裹整个 store,只需给 return 对象标注类型即可,清晰又轻量:
import type { Ref } from 'vue' export const useCartStore = defineStore('cart', () => { const items = ref>([]) const total = computed(() => items.value.reduce((sum, i) => sum + i.qty, 0)) function addItem(item: { id: number; name: string; qty?: number }) { items.value.push({ ...item, qty: item.qty ?? 1 }) } return { items, total, addItem } as const // 推荐用 const 断言 + 类型推导,或显式写接口 })
逻辑复用?直接封装成可组合函数(composable)再导入 把通用逻辑抽成独立函数,比如用户权限、请求状态管理,然后在 store 里调用,完全复用 setup 中的习惯: 新建
composables/useAuth.ts
,导出
useAuthLogic()
在 store 里解构使用:
const { token, login, logout } = useAuthLogic()
store 只负责聚合,逻辑全在 composable 里,测试、复用、维护都更方便 持久化、初始化、服务端预取?用 store 的生命周期钩子 Pinia 提供了
onMounted
(客户端首次激活)、
onUnmounted
和
onServerPrefetch
(仅 SSR),用法和组件内一致:
onMounted(() => { fetchUserData() })
—— 页面挂载时拉用户数据
onServerPrefetch(() => { return fetchProfile() })
—— SSR 时提前取数据 搭配
persist
插件时,初始化逻辑可放在
onMounted
后再恢复状态 不复杂但容易忽略:Pinia 组合式 API 的本质,就是把 setup 的逻辑搬到 store 里,共享 Vue 的响应式系统和生命周期。写熟了,你会发现定义一个 store 和写一个自定义 Hook 几乎一样自然。

相关文章