🧩 Pinia 中文学习文档
📘 一、Pinia 简介
✅ 1. Pinia 是什么?
Pinia 是一个 Vue 的状态管理库,可以理解为新版的 Vuex(但更轻量、语法更现代)。
它的作用是:
- 让组件之间共享数据;
- 管理全局状态(比如登录信息、主题、购物车等);
- 持久化(保存状态到 localStorage);
- 更好的 TypeScript 支持。
📦 二、安装与初始化
1. 安装 Pinia
npm install pinia2. 在 main.js 中引入
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia()) // 挂载全局 Pinia
app.mount('#app')🏗️ 三、定义一个 Store(状态仓库)
Pinia 中的核心概念是 “Store”,相当于一个模块,用来管理一类状态。
示例:定义用户状态
// src/stores/user.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
// 1️⃣ state - 数据
state: () => ({
name: 'Karry',
age: 25,
isLogin: false,
}),
// 2️⃣ getters - 计算属性(类似于 computed)
getters: {
welcomeMessage: (state) => `你好,${state.name}!`,
},
// 3️⃣ actions - 方法(可以包含异步操作)
actions: {
login(name) {
this.name = name
this.isLogin = true
},
logout() {
this.isLogin = false
this.name = ''
},
},
})🎮 四、在组件中使用 Store
<template>
<div>
<h2>{{ userStore.welcomeMessage }}</h2>
<p>年龄:{{ userStore.age }}</p>
<button @click="userStore.login('小明')">登录</button>
<button @click="userStore.logout">退出</button>
</div>
</template>
<script setup>
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
</script>🔍 特点:
userStore是响应式的,可以直接在模板中使用;- 调用
actions就像调用普通方法一样简单。
🧠 五、Store 的核心概念
| 分类 | 用途 | 特点 |
|---|---|---|
state | 存储数据 | 响应式、可直接修改 |
getters | 计算属性 | 类似 computed,自动缓存 |
actions | 方法(同步/异步) | 支持异步请求、业务逻辑 |
🧩 六、支持异步操作
// src/stores/todo.js
import { defineStore } from 'pinia'
export const useTodoStore = defineStore('todo', {
state: () => ({
todos: [],
}),
actions: {
async fetchTodos() {
const res = await fetch('https://jsonplaceholder.typicode.com/todos?_limit=5')
this.todos = await res.json()
},
},
})使用:
<template>
<div>
<button @click="todoStore.fetchTodos">加载任务</button>
<ul>
<li v-for="todo in todoStore.todos" :key="todo.id">{{ todo.title }}</li>
</ul>
</div>
</template>
<script setup>
import { useTodoStore } from '@/stores/todo'
const todoStore = useTodoStore()
</script>💾 七、状态持久化(刷新不丢)
安装插件:
npm install pinia-plugin-persistedstate在 main.js 中注册:
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)在 store 中开启:
export const useUserStore = defineStore('user', {
state: () => ({ name: '', token: '' }),
persist: true // 👈 自动保存到 localStorage
})🧰 八、多个 Store 的配合使用
// user.js
export const useUserStore = defineStore('user', {
state: () => ({ name: 'Karry' })
})
// settings.js
export const useSettingStore = defineStore('settings', {
state: () => ({ theme: 'dark' }),
actions: {
toggleTheme() {
this.theme = this.theme === 'dark' ? 'light' : 'dark'
}
}
})在组件中:
<script setup>
import { useUserStore } from '@/stores/user'
import { useSettingStore } from '@/stores/settings'
const user = useUserStore()
const settings = useSettingStore()
</script>🔄 九、重置 Store 状态
有时候需要“清空”状态,比如退出登录:
userStore.$reset()🧩 十、订阅 Store 的变化(监听状态变化)
userStore.$subscribe((mutation, state) => {
console.log('变化类型:', mutation.type)
console.log('新状态:', state)
})🚀 十一、使用 TypeScript(可选)
Pinia 原生支持 TS:
export const useUserStore = defineStore('user', {
state: (): { name: string; age: number } => ({
name: '',
age: 0,
}),
})TypeScript 会自动推导所有类型,非常友好。
🌈 十二、一个完整示例(用户中心)
<template>
<div class="user-page">
<h2>👋 {{ userStore.name ? userStore.welcomeMessage : "请登录" }}</h2>
<div v-if="!userStore.isLogin">
<input v-model="username" placeholder="请输入用户名" />
<button @click="userStore.login(username)">登录</button>
</div>
<div v-else>
<button @click="userStore.logout">退出登录</button>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useUserStore } from "@/stores/user";
const username = ref("");
const userStore = useUserStore();
</script>
<style scoped>
.user-page {
text-align: center;
padding: 40px;
}
input {
padding: 8px;
border-radius: 6px;
border: 1px solid #ccc;
}
button {
margin-left: 10px;
padding: 8px 14px;
border: none;
border-radius: 6px;
background: #409eff;
color: #fff;
}
</style>📖 十三、常见问题(FAQ)
| 问题 | 解决方案 |
|---|---|
| Pinia 与 Vuex 有什么区别? | Pinia 更轻量、API 简洁,不需要 mutations,更好用。 |
| 能否替代 Vuex? | 可以,Vue3 官方推荐。 |
| 支持 Vue2 吗? | 支持,需配合 Vue 2.7+ 或 @vue/composition-api。 |
| 如何持久化? | 使用 pinia-plugin-persistedstate 插件。 |
| 怎么拆分模块? | 直接创建多个 Store 文件(每个管理一类状态)。 |
🧭 十四、推荐学习路线
| 阶段 | 内容 |
|---|---|
| 入门 | 学习 state、getters、actions 的使用 |
| 进阶 | 学会模块化、异步请求、持久化 |
| 实战 | 将 Pinia 应用于项目(登录、主题、用户信息) |
| 优化 | 学习插件机制、自定义持久化策略 |
评论