跳转到内容

Pinia Store定义

来自代码酷

模板:Note

Pinia Store定义[编辑 | 编辑源代码]

Pinia Store是Pinia状态管理库的核心构建块,用于在Vue应用中集中管理全局状态。与Vuex相比,Pinia提供了更简单的API、TypeScript集成和组合式API支持。

核心概念[编辑 | 编辑源代码]

一个Pinia Store包含三个关键部分:

  • state: 类似组件的data()
  • getters: 类似组件的computed属性
  • actions: 类似组件的methods

pie title Store结构组成 "State" : 45 "Getters" : 25 "Actions" : 30

基础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状态变化可表示为: St+1=A(St,P) 其中:

  • S = 状态
  • A = action函数
  • P = 传入参数

常见问题[编辑 | 编辑源代码]

页面模块:Message box/ambox.css没有内容。

错误示范:

const { count, increment } = useCounterStore() // ✗ 错误

正确做法:

const store = useCounterStore()
const count = storeToRefs(store).count // ✓ 正确

总结[编辑 | 编辑源代码]

Pinia Store通过清晰的结构定义应用状态:

  • 使用defineStore()创建
  • 支持选项式和组合式API
  • 天然支持TypeScript
  • 遵循Vue响应式规则

模板:Tip