文章目录
-
-
- [一、Pinia 核心用途](#一、Pinia 核心用途)
- [二、Pinia 在 Vue3 中的安装与全局配置](#二、Pinia 在 Vue3 中的安装与全局配置)
-
- [1. 安装 Pinia](#1. 安装 Pinia)
- [2. 全局注册 Pinia(核心文件:`src/main.js`)](#2. 全局注册 Pinia(核心文件:
src/main.js))
- [三、创建 Pinia 仓库(核心文件:`src/stores/`)](#三、创建 Pinia 仓库(核心文件:
src/stores/)) -
- [1. 新建仓库文件(以用户信息 + 计数器为例)](#1. 新建仓库文件(以用户信息 + 计数器为例))
- [四、在页面/组件中使用 Pinia(示例页面:`src/views/TestPinia.vue`)](#四、在页面/组件中使用 Pinia(示例页面:
src/views/TestPinia.vue)) - 五、关键注意事项
- 六、流程规范总结
-

一、Pinia 核心用途
Pinia 是 Vue 官方推荐的状态管理库(替代 Vuex),用于集中管理 Vue 应用中跨组件/跨页面共享的数据(如用户信息、全局配置、购物车数据等),核心优势:
- 支持 Vue3 的 Composition API,语法更简洁;
- 无嵌套模块、无命名空间,结构更清晰;
- 内置 TypeScript 支持,类型提示更友好;
- 体积小、性能优,支持热更新和调试工具。
二、Pinia 在 Vue3 中的安装与全局配置
1. 安装 Pinia
bash
# npm 安装
npm install pinia
# yarn 安装
yarn add pinia
# pnpm 安装
pnpm add pinia
2. 全局注册 Pinia(核心文件:src/main.js)
javascript
// src/main.js(Vue3 + Vite 项目)
import { createApp } from 'vue'
import { createPinia } from 'pinia' // 导入 Pinia
import App from './App.vue'
const app = createApp(App)
app.use(createPinia()) // 注册 Pinia 实例
app.mount('#app')
三、创建 Pinia 仓库(核心文件:src/stores/)
1. 新建仓库文件(以用户信息 + 计数器为例)
创建目录 src/stores/,新建 userStore.js(或 userStore.ts,推荐 TS):
javascript
// src/stores/userStore.js
import { defineStore } from 'pinia'
// 定义并导出仓库(第一个参数是仓库唯一 ID,必须唯一)
export const useUserStore = defineStore('user', {
// 1. 状态:存储共享数据(类似 Vue 的 data)
state: () => ({
username: '未登录', // 用户名
token: '', // 用户令牌
count: 0 // 测试用计数器
}),
// 2. 计算属性:基于 state 派生数据(类似 Vue 的 computed)
getters: {
// 示例:格式化用户名
formatUsername: (state) => `当前用户:${state.username}`,
// 示例:计数器翻倍(可调用其他 getters)
doubleCount: (state) => state.count * 2
},
// 3. 方法:修改状态的逻辑(类似 Vue 的 methods,支持异步)
actions: {
// 同步修改状态
setUserInfo(username, token) {
this.username = username
this.token = token
},
// 异步修改状态(如请求接口后更新)
async login(userData) {
// 模拟接口请求
const res = await new Promise((resolve) => {
setTimeout(() => resolve({ username: userData.name, token: 'xxx-123-yyy' }), 1000)
})
// 更新状态
this.setUserInfo(res.username, res.token)
},
// 计数器自增
increment() {
this.count++
}
}
})
四、在页面/组件中使用 Pinia(示例页面:src/views/TestPinia.vue)
vue
<template>
<div class="pinia-test">
<h3>Pinia 状态管理测试</h3>
<!-- 1. 展示 state 数据 -->
<div>
<p>用户名:{{ userStore.username }}</p>
<p>Token:{{ userStore.token }}</p>
<p>计数器:{{ userStore.count }}</p>
</div>
<!-- 2. 展示 getters 派生数据 -->
<div>
<p>格式化用户名:{{ userStore.formatUsername }}</p>
<p>计数器翻倍:{{ userStore.doubleCount }}</p>
</div>
<!-- 3. 调用 actions 修改状态 -->
<div>
<button @click="handleLogin">模拟登录</button>
<button @click="userStore.increment">计数器+1</button>
<button @click="handleReset">重置状态</button>
</div>
<!-- 4. 直接修改 state(不推荐,仅演示) -->
<div>
<input v-model="userStore.username" placeholder="直接修改用户名" />
</div>
</div>
</template>
<script setup>
// 导入仓库
import { useUserStore } from '@/stores/userStore'
// 实例化仓库(注意:每次调用都是同一个实例,无需担心重复创建)
const userStore = useUserStore()
// 模拟登录方法
const handleLogin = async () => {
await userStore.login({ name: '张三' })
alert('登录成功!')
}
// 重置仓库状态(Pinia 内置方法)
const handleReset = () => {
userStore.$reset()
}
/* 额外:批量修改 state 的方式(推荐) */
// userStore.$patch({
// count: 10,
// username: '李四'
// })
// 或函数式 patch(适合复杂逻辑)
// userStore.$patch((state) => {
// state.count += 5
// state.token = ''
// })
</script>
<style scoped>
.pinia-test {
padding: 20px;
}
button {
margin: 0 10px 10px 0;
padding: 5px 10px;
}
</style>
五、关键注意事项
-
仓库 ID 唯一性 :
defineStore的第一个参数(如'user')是仓库唯一标识,不能重复,否则会导致状态混乱; -
修改状态的规范 :
- 推荐通过
actions修改 state(便于统一管理逻辑、调试和扩展); - 禁止直接修改 state(除非简单场景),批量修改优先用
$patch;
- 推荐通过
-
解构 state 的坑 :直接解构
const { count } = userStore会丢失响应式,需用storeToRefs:javascriptimport { storeToRefs } from 'pinia' const { count, username } = storeToRefs(userStore) // 保留响应式 -
actions 支持异步 :无需像 Vuex 那样区分
actions/mutations,直接在 actions 中写异步逻辑(如接口请求); -
TypeScript 支持 :若用 TS,建议给 state/getters/actions 加类型注解,示例:
typescript// src/stores/userStore.ts import { defineStore } from 'pinia' interface UserState { username: string token: string count: number } export const useUserStore = defineStore<'user', UserState>( 'user', { state: (): UserState => ({ username: '未登录', token: '', count: 0 }), // ... 其他配置 } ) -
调试工具:Vue Devtools 已支持 Pinia,可直接在调试面板查看/修改仓库状态;
-
部署持久化 :Pinia 是纯前端状态管理,刷新页面后状态会丢失,若需持久化(如用户信息),需结合
pinia-plugin-persistedstate:bash# 安装持久化插件 npm install pinia-plugin-persistedstate配置插件(
src/main.js):javascriptimport { createApp } from 'vue' import { createPinia } from 'pinia' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' import App from './App.vue' const pinia = createPinia() pinia.use(piniaPluginPersistedstate) // 注册持久化插件 createApp(App).use(pinia).mount('#app')仓库开启持久化:
javascriptexport const useUserStore = defineStore('user', { state: () => ({ ... }), persist: true, // 开启持久化(默认存储在 localStorage) // 自定义持久化配置 // persist: { // key: 'user-info', // 存储的 key 名 // storage: sessionStorage, // 存储位置(sessionStorage) // paths: ['username', 'token'] // 只持久化指定字段 // } })
六、流程规范总结
- 核心流程:安装 Pinia → 全局注册 → 创建仓库(state/getters/actions)→ 组件中导入并使用仓库;
- 核心规范 :优先通过
actions修改状态,解构 state 用storeToRefs保留响应式,仓库 ID 必须唯一; - 扩展能力 :结合
pinia-plugin-persistedstate实现状态持久化,解决刷新丢失问题。