Pinia 核心概念 #
概述 #
Pinia 只有三个核心概念,这使得它比其他状态管理库更简单易学:
text
Pinia 核心概念
├── State ────── 状态数据(类似 data)
├── Getters ──── 计算属性(类似 computed)
└── Actions ──── 方法(类似 methods)
State(状态) #
State 是 Store 的核心,用于存储应用的状态数据。
定义 State #
State 必须是一个返回初始状态的函数:
ts
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
name: 'John',
age: 25,
email: 'john@example.com',
isAdmin: false
})
})
访问 State #
vue
<template>
<div>
<p>姓名: {{ userStore.name }}</p>
<p>年龄: {{ userStore.age }}</p>
</div>
</template>
<script setup>
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
</script>
解构 State #
直接解构会失去响应性,需要使用 storeToRefs:
vue
<script setup>
import { storeToRefs } from 'pinia'
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
// 错误:失去响应性
const { name, age } = userStore
// 正确:保持响应性
const { name, age } = storeToRefs(userStore)
</script>
修改 State #
有多种方式修改 State:
ts
// 方式1:直接修改
userStore.name = 'Jane'
// 方式2:使用 $patch(批量修改)
userStore.$patch({
name: 'Jane',
age: 26
})
// 方式3:使用 $patch 函数(适合复杂逻辑)
userStore.$patch((state) => {
state.name = 'Jane'
state.age++
})
// 方式4:通过 Actions 修改(推荐)
userStore.updateProfile({ name: 'Jane', age: 26 })
重置 State #
使用 $reset 方法将 State 重置为初始值:
ts
const userStore = useUserStore()
userStore.$reset()
替换 State #
使用 $state 完全替换状态:
ts
userStore.$state = {
name: 'New User',
age: 30,
email: 'new@example.com',
isAdmin: true
}
Getters(计算属性) #
Getters 用于定义派生状态,类似于 Vue 的 computed 属性。
定义 Getters #
ts
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
getters: {
// 基础 getter
doubleCount: (state) => state.count * 2,
// 使用 this 访问其他 getter
doubleCountPlusOne() {
return this.doubleCount + 1
}
}
})
访问其他 Store #
ts
export const useCartStore = defineStore('cart', {
state: () => ({
items: []
}),
getters: {
summary() {
const userStore = useUserStore()
return `${userStore.name} 的购物车有 ${this.items.length} 件商品`
}
}
})
传递参数 #
Getters 本身不支持参数,但可以返回一个函数:
ts
export const useUserStore = defineStore('user', {
state: () => ({
users: [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Bob' }
]
}),
getters: {
getUserById: (state) => {
return (id: number) => state.users.find(user => user.id === id)
}
}
})
vue
<template>
<p>{{ userStore.getUserById(1)?.name }}</p>
</template>
TypeScript 类型 #
ts
interface User {
id: number
name: string
email: string
}
export const useUserStore = defineStore('user', {
state: () => ({
users: [] as User[]
}),
getters: {
userCount: (state): number => state.users.length,
getUserById: (state) => (id: number): User | undefined => {
return state.users.find(user => user.id === id)
}
}
})
Actions(方法) #
Actions 用于定义业务逻辑,可以包含同步和异步操作。
定义 Actions #
ts
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
},
incrementBy(amount: number) {
this.count += amount
},
reset() {
this.count = 0
}
}
})
异步 Actions #
ts
export const useProductStore = defineStore('product', {
state: () => ({
products: [],
loading: false,
error: null
}),
actions: {
async fetchProducts() {
this.loading = true
this.error = null
try {
const response = await fetch('/api/products')
this.products = await response.json()
} catch (error) {
this.error = error.message
} finally {
this.loading = false
}
}
}
})
调用其他 Actions #
ts
export const useCartStore = defineStore('cart', {
state: () => ({
items: [],
total: 0
}),
actions: {
addItem(item) {
this.items.push(item)
this.calculateTotal()
},
removeItem(itemId) {
this.items = this.items.filter(item => item.id !== itemId)
this.calculateTotal()
},
calculateTotal() {
this.total = this.items.reduce((sum, item) => sum + item.price, 0)
}
}
})
访问其他 Store #
ts
export const useOrderStore = defineStore('order', {
state: () => ({
orders: []
}),
actions: {
async createOrder() {
const cartStore = useCartStore()
const userStore = useUserStore()
const order = {
userId: userStore.id,
items: cartStore.items,
total: cartStore.total
}
// 创建订单...
this.orders.push(order)
// 清空购物车
cartStore.clearCart()
}
}
})
使用 Composition API 风格 #
Actions 可以使用 async/await:
ts
export const useAuthStore = defineStore('auth', {
state: () => ({
user: null,
token: null
}),
actions: {
async login(credentials) {
const response = await api.login(credentials)
this.user = response.user
this.token = response.token
},
async logout() {
await api.logout()
this.user = null
this.token = null
}
}
})
完整示例 #
下面是一个完整的用户管理 Store 示例:
ts
// stores/user.ts
import { defineStore } from 'pinia'
interface User {
id: number
name: string
email: string
role: 'admin' | 'user'
}
interface UserState {
users: User[]
currentUser: User | null
loading: boolean
error: string | null
}
export const useUserStore = defineStore('user', {
state: (): UserState => ({
users: [],
currentUser: null,
loading: false,
error: null
}),
getters: {
userCount: (state) => state.users.length,
isAdmin: (state) => state.currentUser?.role === 'admin',
getUserById: (state) => (id: number) => {
return state.users.find(user => user.id === id)
},
activeUsers: (state) => {
return state.users.filter(user => user.email)
}
},
actions: {
async fetchUsers() {
this.loading = true
this.error = null
try {
const response = await fetch('/api/users')
this.users = await response.json()
} catch (error) {
this.error = error.message
} finally {
this.loading = false
}
},
async login(email: string, password: string) {
this.loading = true
this.error = null
try {
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password })
})
this.currentUser = await response.json()
} catch (error) {
this.error = error.message
} finally {
this.loading = false
}
},
logout() {
this.currentUser = null
},
updateUser(id: number, updates: Partial<User>) {
const index = this.users.findIndex(user => user.id === id)
if (index !== -1) {
this.users[index] = { ...this.users[index], ...updates }
}
}
}
})
下一步 #
现在你已经掌握了 Pinia 的核心概念,接下来让我们深入学习如何定义和使用 Store。
- 定义 Store - 创建状态仓库
最后更新:2026-03-28