Pinia 仓库结构优化:实战最佳实践
在大型 Vue 项目中,Pinia 仓库往往迅速膨胀,维护起来如噩梦一般。采用坚实的结构就能彻底解决:仅通过 actions 修改状态、使用 setup 语法,并在仓库内避免副作用。这让中高级开发者能轻松预测和测试代码。
仅通过 Actions 修改状态
组件直接修改状态会模糊职责分工。以下是问题代码示例:
const docStore = useDocumentStore()
const { client } = storeToRefs(docStore)
client.value = null // 状态修改逻辑四处散乱
久而久之,调试变得不可能,因为变更散布在各个组件中。解决方案?集中化 actions:
export const useDocumentStore = defineStore('documents', () => {
const client = ref(null)
const resetClient = () => { client.value = null }
return { client, resetClient }
})
// 在组件中使用
docStore.resetClient()
单一入口点,便于添加验证、日志或埋点,而无需到处修改代码。
优先使用 Setup 仓库而非 Options API
Options API 在仓库中已过时。Setup 风格(defineStore(() => { ... }))带来:
- 无需
this的透明响应式。 - 测试更简单。
- 与 composables 无缝集成。
代码更简洁,响应式体验与组件一致。新建仓库必须切换——效果立竿见影。
仓库内摒弃 Watchers
仓库内的 watchers 会因状态变更触发隐藏副作用,调试难度飙升。仓库只需持有数据,不应派发事件。
用组件或 composables 的显式调用替换 watchers。路由变更、URL 解析或外部事件等,都移到外部处理,通过 actions 传入就绪数据。
通过插件实现持久化
与 localStorage 同步不应混入业务逻辑。使用 pinia-plugin-persistedstate 或自定义测试过的封装。
避免在 actions 中直接调用 localStorage.setItem——这破坏仓库纯净性,阻碍重构。
仓库仅作纯数据容器
仓库只负责读取、保存和更新数据。将以下逻辑移出:
- 路由订阅。
- Token 解析。
- WebSocket 处理。
- 跨仓库计算。
提交前检查清单:
- 这个仓库能否替换为纯常量和函数的文件,而不破坏架构?
- 如果不能,就是功能超载——提取逻辑。
核心要点
- 集中化修改: 通过 actions,而非直接访问 ref。
- Setup 语法: 测试更易,无
this困扰。 - 无 watchers: 副作用外置,仓库保持可预测。
- 持久化分离: 用插件,而非塞进 actions。
- 单一职责: 复杂逻辑交给 composables。
这种方法让仓库保持精瘦、可 mock、重构友好。项目易于维护,好习惯迅速养成。
— Editorial Team
暂无评论。