Pinia 是 Vue 官方推荐的新一代状态管理库,专为 Vue 3 设计(同时兼容 Vue 2),它简化了状态管理流程,并优化了 TypeScript 支持。以下从核心概念、使用方法和与 Vuex 的对比三方面详细说明:
一、Pinia 的核心概念与特点
精简架构
- 无 Mutation:直接通过
actions
修改状态(同步/异步均可),无需commit
。 - 扁平化 Store:每个 Store 独立管理(如
useUserStore
、useCartStore
),无需嵌套模块或命名空间。 - 响应式状态:基于 Vue 3 的
reactive
实现,直接修改状态自动触发更新。
- 无 Mutation:直接通过
TypeScript 友好
- 开箱即用的类型推断,无需额外类型声明。
轻量高效
- 体积仅约 1KB(gzip),性能优于 Vuex。
二、基本使用
<template>
<div>实际参数={{count}}</div>
<div>
<button @click="addByPina">点击</button>
</div>
</template>
<script setup lang="ts">
import {useCounterStore} from "@/stores/counter.ts";
import {storeToRefs} from "pinia";
const useCounter = useCounterStore()
let {count} = storeToRefs(useCounter)
// 第1种直接修改pina中数据
function add () {
count.value++
}
// 第2种利用$patch 批量修改
useCounter.$patch({
count: 100
})
// 可直接使用pina的方法
function addByPina () {
useCounter.increment()
}
// 通过subscribe方法监听state变化
useCounter.$subscribe((mutation, state)=>{
console.log('$subscribe ===', mutation, state)
})
</script>
三、Pinia 与 Vuex 的核心区别
特性 | Pinia | Vuex |
---|---|---|
架构 | 多 Store 独立管理(扁平化) | 单一 Store + 嵌套 Modules |
状态更新 | 直接修改 state ,无需 Mutation |
必须通过 commit 触发 Mutation |
异步处理 | Actions 直接修改状态 | Actions 需调用 Mutations 更新状态 |
TypeScript | 原生类型推断,零配置支持 | 需手动声明类型,配置复杂 |
模块化 | 文件即模块(如 userStore.ts ) |
需 namespaced: true 避免命名冲突 |
代码简洁度 | 减少 40% 样板代码(无 Mutation) | 冗余代码多(State + Mutation + Action) |
DevTools | 支持时间旅行调试,结构扁平更清晰 | 支持但嵌套模块路径深 |
适用场景 | Vue 3 新项目、TS 项目、快速迭代 | 大型遗留项目、需兼容 Vue 2 |
四、Pinia原理
模块化设计
每个 Store 独立定义(defineStore
),通过唯一 ID 注册到全局 Pinia 实例的 Map 中。Store 之间完全隔离,无命名空间冲突。响应式绑定
使用 Vue 的reactive()
将 State 转为响应式对象,Getter 通过computed
实现缓存。解构时用storeToRefs
将状态转为 Ref 保持响应性。状态直改机制
移除 Vuex 的 Mutation 层,允许在 Action 中直接修改 State(通过this.state
操作),同步/异步操作统一处理。依赖注入
通过 Vue 的provide/inject
实现跨组件访问:useStore()
内部inject
获取 Pinia 实例- 从全局 Map 中检索对应 Store
初始化流程
- 执行
useStore()
时,若 Store 不存在:- 选项式:自动包装 State(
reactive
)、Getter(computed
) - 组合式:直接执行 setup 函数(类似组件逻辑)
- 选项式:自动包装 State(
- 缓存 Store 实例避免重复创建
- 执行
插件扩展
通过pinia.use()
添加插件,可拦截:- Store 创建(添加新属性/方法)
- Action 执行(日志/监控)
- 状态变更(持久化存储)
性能优化
- 用
markRaw
标记 Pinia 实例避免被转为响应式 - 精准响应式绑定(仅 State/Getter 响应,Action 不代理)
- 用
本质:Pinia 是 Vue 响应式系统的增强应用,通过精简 API 设计(去 Mutation)+ 复用 Composition API 能力,提供比 Vuex 更简洁高效的状态管理。
五、何时选择 Pinia?
- 推荐 Pinia:
- Vue 3 新项目、需深度 TypeScript 集成、追求简洁代码。
- 示例:动态权限管理、跨组件表单状态共享。
- 保留 Vuex:
- 维护 Vue 2 旧项目、需兼容深度嵌套模块的复杂场景。
迁移建议:小型项目直接重写为 Pinia;大型项目逐步替换模块,利用
$patch
兼容旧逻辑。
附:Pinia 进阶技巧
插件扩展:
使用 pinia-plugin-persistedstate
实现状态持久化。
Pinia 通过简化 API 和强化 TypeScript 支持,大幅提升了开发体验。其设计理念更贴合 Vue 3 的响应式系统,是未来 Vue 生态状态管理的首选方案。