引言
大家好,欢迎来到第11期的 JavaScript 库推荐!本期为大家介绍的是 Pinia------Vue 官方推荐的状态管理库。它以组合式 API 为核心,兼具直观、类型安全、轻量与可扩展的特点,能高效解决多组件共享状态、复杂业务流转与工程化可观测性不足的痛点,适合中大型 Vue 3 项目与 Nuxt 3 应用。
本文将从 Pinia 的核心特性、安装使用、实际应用、最佳实践与进阶用法等维度展开,帮助你系统掌握该库的使用方法。
库介绍
基本信息
- 库名称:Pinia
- GitHub 地址:github.com/vuejs/pinia
- npm 地址:www.npmjs.com/package/pin...
- 官方文档:pinia.vuejs.org/
- GitHub Stars:约 14.3k(以发布页为准)
- 最新版本:3.0.4(以 npm 为准)
- 包大小:~1.5KB(压缩后,官方文档)
- 维护状态:活跃维护
主要特性
- 直观:API 贴近组件设计,学习成本低。
- 类型安全:完善推断与补全,JS 项目亦有良好提示。
- DevTools:与 Vue DevTools 深度整合,时间线与状态快照清晰。
- 可扩展:插件机制可拦截动作、持久化、记录事务等。
- 模块化:天然支持多 Store,自动 Tree-shaking。
- 轻量:极小体积,几乎无感开销。
兼容性
- 浏览器支持:现代浏览器(与 Vue 3 要求一致)。
- Node.js 支持:可用于 SSR(Vue 3 / Nuxt 3)。
- 框架兼容:Vue 3、Nuxt 3(官方模块
@pinia/nuxt)。 - TypeScript 支持:≥ 4.5(Pinia 3.x 要求)。
安装使用
安装方式(仅 pnpm)
bash
pnpm add pinia
基础使用
ts
import { createApp } from 'vue'
import { createPinia, defineStore } from 'pinia'
import { ref, computed } from 'vue'
import App from './App.vue'
// 创建并注册 Pinia
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
// Setup 风格 Store(推荐)
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubled = computed(() => count.value * 2)
const increment = () => { count.value += 1 }
const reset = () => { count.value = 0 }
return { count, doubled, increment, reset }
})
app.mount('#app')
配置选项(插件示例)
ts
/**
* 选择性持久化插件:仅持久化指定字段
* @param {{ store: any, options: Record<string, any> }} ctx - 插件上下文
* @returns {void}
*/
const persistSelectivePlugin = ({ store, options }) => {
const cfg = options?.persist
if (!cfg) return
const key = `pinia:${store.$id}`
const pick = (obj, paths) => paths.reduce((acc, k) => (acc[k] = obj[k], acc), {})
const cached = localStorage.getItem(key)
if (cached) store.$patch(JSON.parse(cached))
store.$subscribe((_m, state) => {
const data = Array.isArray(cfg.paths) ? pick(state, cfg.paths) : state
localStorage.setItem(key, JSON.stringify(data))
}, { detached: true })
}
import { createPinia } from 'pinia'
const pinia = createPinia()
pinia.use(persistSelectivePlugin)
实际应用
应用场景1:用户认证与权限
ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useAuthStore = defineStore('auth', () => {
const token = ref('')
const roles = ref([])
const isAuthed = computed(() => token.value !== '')
const login = async () => { token.value = 'mock-token'; roles.value = ['user'] }
const logout = () => { token.value = ''; roles.value = [] }
return { token, roles, isAuthed, login, logout }
})
应用场景2:购物车状态管理
ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCartStore = defineStore('cart', () => {
const items = ref([])
const total = computed(() => items.value.reduce((s, i) => s + i.price * i.qty, 0))
const add = (p) => { items.value.push({ ...p, qty: 1 }) }
const remove = (id) => { items.value = items.value.filter(i => i.id !== id) }
const clear = () => { items.value = [] }
return { items, total, add, remove, clear }
})
优缺点分析
优点 ✅
- 直观易上手:贴近 Vue 组合式 API。
- 类型与调试友好:类型推断 + DevTools 集成。
- 可扩展:插件、订阅与动作拦截完善。
- 模块化与轻量:Tree-shaking 与极小体积。
缺点 ❌
- Vue 专用:不适用于非 Vue 技术栈。
- 旧浏览器限制:与 Vue 3 一致,需现代环境。
- 选项式 actions 与箭头函数:无法使用
this,建议改用 Setup 风格或外部纯函数。
最佳实践
开发建议
1. 性能优化技巧
ts
// 精准订阅:storeToRefs 保持解构后的响应式
import { storeToRefs } from 'pinia'
const { count, doubled } = storeToRefs(useCounterStore())
// 批量更新:使用函数式 $patch,避免多次变更
const patchFn = (store) => { store.$patch((s) => { s.count += 2 }) }
// 解耦订阅:detached 避免组件销毁自动取消
const subscribeChanges = (store) => {
store.$subscribe((_m, state) => console.log('state:', state), { detached: true })
}
2. 错误处理策略
ts
// 使用 $onAction 记录完成与错误,辅助定位
const watchActions = (store) => {
store.$onAction(({ name, after, onError }) => {
const t = performance.now()
after(() => console.log(`${name} done`, Math.round(performance.now() - t), 'ms'))
onError((e) => console.error(`${name} error`, e))
})
}
3. 内存与资源管理
ts
// 路由切换或组件卸载时重置临时状态
const resetState = (store) => { store.$reset?.() /* Setup 风格自定义 reset */ }
// 持久化仅保留必要字段,避免写入大对象或隐私数据
常见陷阱
- 选项式 actions + 箭头函数的
this:改用 Setup 风格或外部函数。 - 直接解构丢响应:使用
storeToRefs。 - Store 间循环依赖:抽到服务层或组件组合调用。
- 过度持久化:谨慎选择字段与存储策略。
进阶用法
高级特性示例
ts
// 插件:动作日志
const actionLoggerPlugin = ({ store }) => {
store.$onAction(({ name, after, onError }) => {
const start = performance.now()
after(() => console.log(`[action] ${name}`, Math.round(performance.now() - start), 'ms'))
onError((err) => console.error(`[action] ${name} error:`, err))
})
}
// SSR:序列化 pinia.state.value 并在客户端回填
// HMR:acceptHMRUpdate(useXxxStore, import.meta.hot)
总结
Pinia 以直观、类型安全与可扩展著称,是管理 Vue 3 复杂状态的首选方案。建议优先使用 Setup 风格编写 Store,搭配 storeToRefs 精准订阅与插件机制实现持久化与可观测性;对大型应用按领域拆分 Store,并为关键动作做好命名与日志。
参考与链接
- 官方仓库:github.com/vuejs/pinia
- 官方文档:pinia.vuejs.org/
- Releases(版本与变更):github.com/vuejs/pinia...