pinia 是中大型 vue3 应用重构的起点,需按业务域拆分 store、用 actions 统一数据操作、通过依赖注入实现跨 store 通信、结合持久化插件分场景缓存,推动状态职责归位。

Pinia 不是给小项目“加个状态管理”那么简单,而是中大型 Vue3 应用重构的起点——它直接决定了模块可维护性、跨域协作效率和长期迭代成本。重构不是把 Vuex 换成 Pinia,而是借机重新梳理状态边界、通信逻辑和工程规范。
按业务域拆分 Store,拒绝“大而全”的全局 Store
中大型项目常见问题是:一个 store 里塞了用户、权限、配置、通知等所有字段,导致修改一处牵动全局。Pinia 天然支持扁平化模块化,每个业务域独立成 store,命名即契约。
- 按功能边界建 store:比如
useUserStore(登录态、profile)、useCartStore(商品项、优惠计算)、useOrderStore(订单列表、状态流转); - store 文件名与 ID 严格一致(如
userStore.ts中defineStore('user', {...})),避免引用歧义; - 禁止在 store 内 import 其他业务组件或页面,保持纯状态逻辑;公共工具函数统一抽到
composables/下复用。
用 actions 统一数据获取与变更,删掉所有 mutation 式写法
Pinia 的 actions 是唯一入口,同步异步都放这里,既符合直觉,也便于拦截、打点、错误统一处理。
- 异步请求后直接赋值:
this.profile = await api.fetchProfile(),不绕commit; - 复杂变更封装成 action:比如“清空购物车并跳转结算页”,不要在组件里手动重置多个字段;
- 为关键 action 添加 loading 状态和错误标记(如
this.loading = true),组件通过store.loading控制 UI 反馈,而非靠事件或 props 传递。
跨 store 通信走依赖注入,不靠事件总线或 this.$emit
当 cart 需要读 user 的等级算折扣、order 需要校验 auth 的 token 是否过期,硬编码耦合会毁掉模块独立性。Pinia 支持在 getter 或 action 中直接调用其他 store。
- 在
cartStore的 getter 中调用useUserStore()获取userLevel,自动响应变化; - 避免在组件中同时 use 多个 store 再做逻辑拼接,把关联逻辑下沉到 store 层;
- 若存在循环依赖(A 用 B,B 又用 A),提取共用状态到新 store(如
useAuthStore),作为两者桥梁。
加持久化插件 + 分场景缓存策略,提升用户体验
用户刷新页面后购物车消失、表单草稿丢失,这类问题不用再手写 localStorage 逻辑。Pinia 插件 pinia-plugin-persistedstate 可精准控制哪些字段存、存哪、何时同步。
- 敏感数据(token、密码)绝不持久化;
- 用户偏好(主题色、语言)设为 sessionStorage,关闭标签页即清除;
- 购物车、草稿箱用 localStorage,并配置
key和storage显式指定; - 配合路由守卫,在离开页面前调用
store.$persist()主动保存,避免意外丢失。
重构不是一次替换,而是借 Pinia 推动状态职责归位:谁产生数据、谁消费数据、谁负责清理,每条链路都该清晰可追溯。不复杂但容易忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










