Pinia 状态管理
定义 Store
Section titled “定义 Store”import { defineStore } from 'pinia'import { ref, computed } from 'vue'
// Options API 风格export const useUserStore = defineStore('user', { state: () => ({ name: '', token: '', roles: [] as string[] }),
getters: { isLoggedIn: (state) => !!state.token, hasRole: (state) => (role: string) => state.roles.includes(role) },
actions: { setUser(user: { name: string; token: string }) { this.name = user.name this.token = user.token },
logout() { this.name = '' this.token = '' this.roles = [] } }})
// Composition API 风格export const useCounterStore = defineStore('counter', () => { const count = ref(0) const doubleCount = computed(() => count.value * 2)
function increment() { count.value++ }
return { count, doubleCount, increment }})在组件中使用
Section titled “在组件中使用”<script setup lang="ts">import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
// 读取状态console.log(userStore.name)console.log(userStore.isLoggedIn)
// 修改状态userStore.setUser({ name: 'Admin', token: 'xxx' })
// 调用 actionuserStore.logout()</script>解构与响应性
Section titled “解构与响应性”import { storeToRefs } from 'pinia'
const userStore = useUserStore()
// 错误:失去响应性const { name, token } = userStore
// 正确:使用 storeToRefsconst { name, token } = storeToRefs(userStore)
// actions 不需要 storeToRefsconst { setUser, logout } = userStore使用 pinia-plugin-persistedstate
Section titled “使用 pinia-plugin-persistedstate”import { createPinia } from 'pinia'import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()pinia.use(piniaPluginPersistedstate)
// store 配置export const useUserStore = defineStore('user', { state: () => ({ token: '', userInfo: null }),
persist: { key: 'user-store', storage: localStorage, paths: ['token', 'userInfo'] }})组合式 Store
Section titled “组合式 Store”export const useCartStore = defineStore('cart', () => { const items = ref<CartItem[]>([])
const total = computed(() => items.value.reduce((sum, item) => sum + item.price * item.quantity, 0) )
return { items, total }})
export const useOrderStore = defineStore('order', () => { const cartStore = useCartStore()
async function createOrder() { const orderItems = cartStore.items // 创建订单... cartStore.$reset() }
return { createOrder }})订阅状态变化
Section titled “订阅状态变化”const userStore = useUserStore()
// 订阅 state 变化userStore.$subscribe((mutation, state) => { console.log('Type:', mutation.type) console.log('Store ID:', mutation.storeId) console.log('New State:', state)})
// 订阅 action 调用userStore.$onAction(({ name, args, after, onError }) => { console.log(`Action ${name} called with:`, args)
after((result) => { console.log(`Action ${name} finished:`, result) })
onError((error) => { console.error(`Action ${name} failed:`, error) })})重置与批量更新
Section titled “重置与批量更新”const userStore = useUserStore()
// 重置到初始状态userStore.$reset()
// 批量更新userStore.$patch({ name: 'New Name', token: 'new-token'})
// 批量更新(函数式)userStore.$patch((state) => { state.roles.push('admin')})与 Vue Router 配合
Section titled “与 Vue Router 配合”import { useUserStore } from '@/stores/user'
router.beforeEach((to, from) => { const userStore = useUserStore()
if (to.meta.requiresAuth && !userStore.isLoggedIn) { return { name: 'Login', query: { redirect: to.fullPath } } }})- Store 按功能模块拆分,避免单一巨大 Store
- 敏感数据不要持久化到 localStorage
- 复杂异步逻辑放在 actions 中
- 使用 TypeScript 定义 state 类型
- 合理使用 getters 处理派生状态