Pinia Store定义
外观
Pinia Store定义[编辑 | 编辑源代码]
Pinia Store是Pinia状态管理库的核心构建块,用于在Vue应用中集中管理全局状态。与Vuex相比,Pinia提供了更简单的API、TypeScript集成和组合式API支持。
核心概念[编辑 | 编辑源代码]
一个Pinia Store包含三个关键部分:
state
: 类似组件的data()getters
: 类似组件的computed属性actions
: 类似组件的methods
基础Store定义[编辑 | 编辑源代码]
选项式语法[编辑 | 编辑源代码]
最基础的Store定义方式(兼容Vue 2/3):
import { defineStore } from 'pinia'
// 使用选项式API
export const useCounterStore = defineStore('counter', {
// 状态定义
state: () => ({
count: 0,
user: null
}),
// 计算属性
getters: {
doubleCount: (state) => state.count * 2,
},
// 操作方法
actions: {
increment() {
this.count++
},
async fetchUser(userId) {
this.user = await api.fetchUser(userId)
}
}
})
组合式语法[编辑 | 编辑源代码]
Vue 3推荐写法(类似setup()):
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore('counter', () => {
// state
const count = ref(0)
const user = ref(null)
// getters
const doubleCount = computed(() => count.value * 2)
// actions
function increment() {
count.value++
}
async function fetchUser(userId) {
user.value = await api.fetchUser(userId)
}
return { count, user, doubleCount, increment, fetchUser }
})
类型定义(TypeScript)[编辑 | 编辑源代码]
Pinia提供完整的类型推断:
interface User {
id: number
name: string
}
interface CounterState {
count: number
user: User | null
}
export const useCounterStore = defineStore('counter', {
state: (): CounterState => ({
count: 0,
user: null
}),
// ...其他选项
})
Store实例化[编辑 | 编辑源代码]
在组件中使用Store:
<script setup>
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
// 访问state
console.log(store.count)
// 调用action
store.increment()
</script>
<template>
<div>{{ store.doubleCount }}</div>
</template>
实际应用案例[编辑 | 编辑源代码]
电商购物车[编辑 | 编辑源代码]
export const useCartStore = defineStore('cart', {
state: () => ({
items: [],
discount: 0.1
}),
getters: {
total: (state) => state.items.reduce(
(sum, item) => sum + item.price * item.quantity, 0
),
discountedTotal: (state) => this.total * (1 - state.discount)
},
actions: {
addItem(product, quantity = 1) {
const existing = this.items.find(item => item.id === product.id)
existing
? existing.quantity += quantity
: this.items.push({ ...product, quantity })
},
applyCoupon(code) {
this.discount = validateCoupon(code) ? 0.2 : 0.1
}
}
})
用户认证[编辑 | 编辑源代码]
export const useAuthStore = defineStore('auth', () => {
const user = ref(null)
const isAuthenticated = computed(() => !!user.value)
async function login(credentials) {
user.value = await api.login(credentials)
}
function logout() {
user.value = null
}
return { user, isAuthenticated, login, logout }
})
最佳实践[编辑 | 编辑源代码]
1. 命名规范: 使用useXxxStore
命名约定
2. 单一职责: 每个Store应只管理一个逻辑领域
3. 组合Store: 可通过useStore()
调用其他Store
4. 持久化: 敏感数据不应直接存在Store中
数学表达[编辑 | 编辑源代码]
Store状态变化可表示为: 其中:
- = 状态
- = action函数
- = 传入参数
常见问题[编辑 | 编辑源代码]
页面模块:Message box/ambox.css没有内容。
不要直接解构Store会失去响应性! |
错误示范:
const { count, increment } = useCounterStore() // ✗ 错误
正确做法:
const store = useCounterStore()
const count = storeToRefs(store).count // ✓ 正确
总结[编辑 | 编辑源代码]
Pinia Store通过清晰的结构定义应用状态:
- 使用
defineStore()
创建 - 支持选项式和组合式API
- 天然支持TypeScript
- 遵循Vue响应式规则