Pinia 是 Vue.js 的下一代轻量级状态管理库,由 Vue 核心团队维护。它旨在替代传统的 Vuex,提供更简洁、直观且类型安全的状态管理方案,尤其适合 Vue 3(支持组合式 API)和 TypeScript 项目。
Pinia 的核心特点
1. 轻量且简单
Pinia 的 API 设计比 Vuex 更简洁,移除了 mutations 和 modules 等冗余概念,仅通过 state、getters 和 actions 管理状态。
2. 完全支持 TypeScript
提供完整的类型推断,无需额外配置即可享受类型安全。
3. 组合式 API 友好
天然支持 Vue 3 的组合式 API(setup()),同时兼容选项式 API。
4. 模块化设计
通过定义多个独立的 store 实现模块化,避免全局状态臃肿。
5. DevTools 集成
支持 Vue DevTools,方便调试和跟踪状态变化。
Pinia 与 Vuex 的对比
| 特性 | Pinia | Vuex |
|---|---|---|
| API 复杂度 | 更简单(无 mutations) | 较复杂(需写 mutations) |
| TypeScript 支持 | 原生支持 | 需额外类型定义 |
| 模块化 | 天然支持多 store | 需通过 modules 配置 |
| Vue 版本 | 专为 Vue 3 设计 | 兼容 Vue 2/3 |
| 维护状态 | 官方推荐的未来标准 | 逐渐被 Pinia 取代 |
快速上手
1. 安装
npm install pinia
# 或
yarn add pinia
2. 创建Store
// stores/counter.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
increment() {
this.count++;
},
},
});
3. 在 Vue 组件中使用
<script setup>
import { useCounterStore } from '@/stores/counter';
const counter = useCounterStore();
</script>
<template>
<p>Count: {{ counter.count }}</p>
<p>Double: {{ counter.doubleCount }}</p>
<button @click="counter.increment()">+1</button>
</template>
核心概念
1. State
定义响应式数据:
state: () => ({ user: null, isLoading: false })
2. Getters
计算派生状态(类似 computed):
getters: {
isLoggedIn: (state) => !!state.user,
}
3. Actions
定义方法修改状态(可直接异步):
actions: {
async fetchUser() {
this.isLoading = true;
this.user = await api.getUser();
this.isLoading = false;
},
}
为什么选择 Pinia?
更少的样板代码:无需写 mutations 或 modules。
类型安全:TypeScript 支持开箱即用。
灵活性:兼容 Vue 2/3(需调整版本),适合新旧项目迁移。
官方推荐:Vue 核心团队维护,未来生态更完善。
学习资源
GitHub 仓库:https://github.com/vuejs/pinia
迁移指南:从 Vuex 迁移到 Pinia