Appearance
✨ 状态管理库 👌
快速总览
- 状态管理用于集中管理组件间共享的状态,避免多层级手动传递。
- Vue 官方推荐使用 Pinia(替代 Vuex),API 更简单、类型推断更好。
- 核心概念:
store(数据仓库)、state、getters、actions。 - 常见场景:跨页面共享数据、复杂业务状态、持久化与插件扩展。
状态管理库基本介绍
所谓状态管理库,就是用于管理一个应用中组件的状态的。
传统方式组件之间传递状态:
- 父传子用 Props
- 子传父用 Emit
这种方式存在的问题?
如果你的应用的规模一旦慢慢变大,那么不同层级之间组件的状态传递,就会变得非常的麻烦。

状态管理库如何解决这个问题的?
在状态管理库中,会有一个统一的地方(数据仓库)管理所有的状态,这个时候组件之间要进行状态的传递,只需要一个组件将状态提交到仓库,然后另一个组件从仓库获取最新的状态即可。

何时需要状态管理?
- 层级较深、兄弟/跨页面组件频繁共享数据时。
- 事件与数据流变复杂、调试成本高时。
- 需要统一的行为日志、持久化、或与服务端状态同步时。
Vue 生态的状态管理库
目前,Vue 生态官方所推荐的状态管理库是 Pinia,这是目前最新的状态管理库,用于替代以前的 Vuex 的,因此我们也是以 Pinia 为主,介绍这个最新的状态管理库。
Pinia ,发音为 /piːnjʌ/,来源于西班牙语 piña 。意思为菠萝,表示与菠萝一样,由很多小块组成。在 Pinia 中,每个 Store 都是单独存在,一同进行状态管理。
Pinia 是由 Vue.js 团队成员开发,最初是在 2019 年 11 月左右作为一项实验性工作提出的,目的是为了使用 Composition API 重新设计 Vuex,探索 Vuex 下一次迭代会是什么样子。但是 Pinia 在设计之初就倾向于同时支持 Vue 2 和 Vue 3,并且不强制要求开发者使用组合式 API。在探索的过程中,Pinia 实现了 Vuex5 提案的大部分内容,于是就直接取而代之了。
目前 Vue 官方已经宣布 Pinia 就是新一代的 Vuex,但是为了尊重作者本人,名字保持不变,仍然叫做 Pinia。
与之前的 Vuex 相比,Pinia 提供了更简单的 API,更少的规范,以及 Composition-API 风格的 API 。更重要的是,与 TypeScript 一起使用具有可靠的类型推断支持。
Pinia 官网地址:https://pinia.vuejs.org/

对比之前的 Vuex,Pinia 具有如下的特点:
- mutations 不复存在。只有 state 、getters 、actions
- actions 中支持同步和异步方法修改 state 状态
- 与 TypeScript 一起使用具有可靠的类型推断支持
- 不再有模块嵌套,只有 Store 的概念,Store 之间可以相互调用
- 支持插件扩展,可以非常方便实现本地存储等功能
- 更加轻量,压缩后体积只有 2kb 左右
快速入门(3 步)
- 安装依赖
bash
npm i pinia- 在入口挂载 Pinia
js
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const app = createApp(App);
app.use(createPinia()).mount("#app");- 创建与使用 Store
在 src/stores 目录创建数据仓库。命名约定常用 useXxxStore:
js
// 选项式 Store
import { defineStore } from "pinia";
export const useCounterStore = defineStore("counter", {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++;
},
decrement() {
this.count--;
},
},
});js
// 组合式 Store(推荐与组合式 API 搭配)
import { defineStore } from "pinia";
import { ref, computed } from "vue";
export const useCounterStore = defineStore("counter", () => {
const count = ref(0);
const double = computed(() => count.value * 2);
const increment = () => {
count.value++;
};
const decrement = () => {
count.value--;
};
return { count, double, increment, decrement };
});通过 defineStore 方法来创建一个数据仓库:
- 第一个参数为仓库名称(字符串标识,参与 DevTools 展示与持久化键名)。
- 第二个参数为配置对象或
setup回调,可定义state/getters/actions或以组合式方式返回。
最后在组件中使用 Store:
vue
<template>
<div class="counter">
<h1>计数器:{{ counterStore.count }}(x2: {{ counterStore.double }})</h1>
<button @click="counterStore.increment">增加</button>
<button @click="counterStore.decrement">减少</button>
</div>
</template>
<script setup>
import { useCounterStore } from "./stores/useCounterStore.js";
const counterStore = useCounterStore();
</script>
<style scoped>
.counter {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
</style>目录与命名约定
- Store 文件建议放在
src/stores,命名使用useXxxStore。 - 选项式 Store 更接近 Vuex 心智模型,组合式 Store 与组合式 API 更自然。
- 需要持久化可通过插件或手动
localStorage/IndexedDB;注意序列化与安全。
常见坑
- 忘记在入口通过
app.use(createPinia())安装 Pinia。 - 直接在组件外部使用
useXxxStore()导致共享实例与测试困难(建议仅在setup或生命周期中使用)。 - 重构路径后导入别名错误,建议保持一致的
@/stores或相对路径规范。
