Pinia 简介 #
什么是 Pinia? #
Pinia(发音为 /piːnjʌ/,类似英语中的 “peenya”)是 Vue.js 的专属状态管理库,它允许你跨组件或页面共享状态。Pinia 由 Vue 核心团队成员 Eduardo San Martin Morote 开发,现已成为 Vue 官方推荐的状态管理方案。
为什么叫 Pinia? #
Pinia 在西班牙语中意为"菠萝"。菠萝单独看起来是一个独立的水果,但实际上它是由许多小浆果聚合成的一个整体。这恰好象征了 Pinia 的设计理念:每个 Store 都是独立的,但它们共同组成了完整的状态管理系统。
Pinia 的特点 #
1. 简洁的 API #
Pinia 的 API 非常简洁,只有三个核心概念:
text
Pinia 核心
├── State ────── 状态数据
├── Getters ──── 计算属性
└── Actions ──── 方法(同步/异步)
2. 完整的 TypeScript 支持 #
Pinia 从设计之初就考虑了 TypeScript,提供开箱即用的类型推断:
ts
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
name: 'John',
age: 25
}),
getters: {
isAdult: (state) => state.age >= 18
},
actions: {
updateAge(newAge: number) {
this.age = newAge
}
}
})
3. 无需 mutations #
与 Vuex 不同,Pinia 移除了 mutations 的概念:
ts
// Vuex 方式
mutations: {
increment(state) {
state.count++
}
}
// Pinia 方式 - 直接修改或使用 actions
actions: {
increment() {
this.count++ // 直接修改
}
}
4. 天然模块化 #
每个 Store 都是独立的,无需像 Vuex 那样手动配置 modules:
ts
// stores/user.ts
export const useUserStore = defineStore('user', { /* ... */ })
// stores/cart.ts
export const useCartStore = defineStore('cart', { /* ... */ })
// stores/product.ts
export const useProductStore = defineStore('product', { /* ... */ })
5. 支持多个 Store 实例 #
Pinia 支持在同一应用中创建多个 Pinia 实例,适用于测试或微前端场景:
ts
import { createPinia } from 'pinia'
const pinia1 = createPinia()
const pinia2 = createPinia()
Pinia vs Vuex #
| 特性 | Pinia | Vuex |
|---|---|---|
| API 复杂度 | 简单,只有 state/getters/actions | 复杂,有 state/getters/mutations/actions |
| TypeScript | 原生支持,完整类型推断 | 需要额外配置 |
| 模块化 | 自动,每个 store 独立 | 需要手动配置 modules |
| Mutations | 无 | 必须通过 mutations 修改状态 |
| 代码分割 | 容易 | 需要额外配置 |
| DevTools | 完整支持 | 完整支持 |
| 包体积 | ~1KB | ~3KB |
| 学习曲线 | 低 | 中 |
什么时候使用 Pinia? #
适合使用 Pinia 的场景 #
- 跨组件共享状态:多个组件需要访问同一状态
- 复杂应用状态:应用有复杂的状态逻辑
- 需要状态持久化:需要将状态保存到本地存储
- 大型应用:需要模块化管理状态
- TypeScript 项目:需要完整的类型支持
不需要状态管理的场景 #
- 简单应用:组件间不需要共享状态
- 父子组件通信:使用 props/emit 即可
- 临时状态:使用组件内部 state 即可
Pinia 的设计理念 #
单一职责 #
每个 Store 只负责一个领域:
ts
// 用户相关状态
export const useUserStore = defineStore('user', { /* ... */ })
// 购物车相关状态
export const useCartStore = defineStore('cart', { /* ... */ })
// 产品相关状态
export const useProductStore = defineStore('product', { /* ... */ })
扁平化结构 #
Pinia 采用扁平化的 Store 结构,避免了 Vuex 的嵌套模块问题:
text
Vuex 结构(嵌套)
├── modules
│ ├── user
│ │ └── modules
│ │ └── profile
│ └── cart
Pinia 结构(扁平)
├── stores
│ ├── user.ts
│ ├── profile.ts
│ └── cart.ts
组合式设计 #
Pinia 支持两种定义 Store 的方式:
ts
// Options API 风格
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2
},
actions: {
increment() { this.count++ }
}
})
// Setup 风格(组合式 API)
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() { count.value++ }
return { count, double, increment }
})
Pinia 生态系统 #
text
Pinia 生态系统
├── pinia ──────────────────── 核心库
├── pinia-plugin-persistedstate ─ 状态持久化插件
├── @pinia/nuxt ────────────── Nuxt.js 集成
├── @pinia/testing ─────────── 测试工具
└── Vue DevTools ───────────── 调试支持
下一步 #
现在你已经了解了 Pinia 的基本概念,接下来让我们学习如何安装和配置 Pinia。
- 安装与配置 - 搭建 Pinia 开发环境
最后更新:2026-03-28