Pinia 项目结构 #
基本结构 #
推荐目录结构 #
text
src/
├── stores/
│ ├── index.ts # Store 导出和 Pinia 配置
│ ├── user.ts # 用户相关 Store
│ ├── cart.ts # 购物车 Store
│ ├── product.ts # 产品 Store
│ └── types/
│ └── index.ts # Store 类型定义
├── composables/
│ ├── useAsync.ts # 异步处理
│ └── usePagination.ts # 分页处理
└── main.ts
模块化结构 #
对于大型项目,按功能模块组织:
text
src/
├── stores/
│ ├── index.ts
│ ├── modules/
│ │ ├── auth/
│ │ │ ├── index.ts
│ │ │ ├── user.ts
│ │ │ └── session.ts
│ │ ├── shop/
│ │ │ ├── index.ts
│ │ │ ├── cart.ts
│ │ │ ├── product.ts
│ │ │ └── order.ts
│ │ └── admin/
│ │ ├── index.ts
│ │ └── dashboard.ts
│ └── shared/
│ ├── theme.ts
│ └── locale.ts
Store 文件组织 #
单文件 Store #
适用于简单的 Store:
ts
// stores/user.ts
import { defineStore } from 'pinia'
interface User {
id: number
name: string
email: string
}
interface UserState {
user: User | null
token: string | null
loading: boolean
}
export const useUserStore = defineStore('user', {
state: (): UserState => ({
user: null,
token: null,
loading: false
}),
getters: {
isAuthenticated: (state) => !!state.token,
displayName: (state) => state.user?.name || 'Guest'
},
actions: {
async login(email: string, password: string) {
// ...
},
logout() {
this.user = null
this.token = null
}
}
})
// 导出类型
export type { User, UserState }
多文件 Store #
对于复杂的 Store,拆分为多个文件:
text
stores/
├── user/
│ ├── index.ts # Store 定义
│ ├── state.ts # State 定义
│ ├── getters.ts # Getters 定义
│ ├── actions.ts # Actions 定义
│ └── types.ts # 类型定义
ts
// stores/user/types.ts
export interface User {
id: number
name: string
email: string
}
export interface UserState {
user: User | null
token: string | null
loading: boolean
error: string | null
}
ts
// stores/user/state.ts
import type { UserState } from './types'
export const initialState: UserState = {
user: null,
token: null,
loading: false,
error: null
}
ts
// stores/user/getters.ts
import type { UserState } from './types'
export const getters = {
isAuthenticated: (state: UserState) => !!state.token,
displayName: (state: UserState) => state.user?.name || 'Guest',
isAdmin: (state: UserState) => state.user?.role === 'admin'
}
ts
// stores/user/actions.ts
import type { User, UserState } from './types'
export const actions = {
async login(this: any, email: string, password: string) {
this.loading = true
this.error = null
try {
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
})
const data = await response.json()
this.user = data.user
this.token = data.token
} catch (e) {
this.error = e instanceof Error ? e.message : 'Login failed'
} finally {
this.loading = false
}
},
logout(this: any) {
this.user = null
this.token = null
}
}
ts
// stores/user/index.ts
import { defineStore } from 'pinia'
import { initialState } from './state'
import { getters } from './getters'
import { actions } from './actions'
export const useUserStore = defineStore('user', {
state: () => ({ ...initialState }),
getters,
actions
})
export * from './types'
统一导出 #
stores/index.ts #
ts
// stores/index.ts
import { createPinia } from 'pinia'
export const pinia = createPinia()
// 导出所有 Store
export * from './user'
export * from './cart'
export * from './product'
export * from './order'
// 导出类型
export * from './types'
按模块导出 #
ts
// stores/modules/auth/index.ts
export * from './user'
export * from './session'
// stores/modules/shop/index.ts
export * from './cart'
export * from './product'
export * from './order'
// stores/index.ts
export * from './modules/auth'
export * from './modules/shop'
export * from './modules/admin'
export * from './shared'
类型定义组织 #
集中管理类型 #
ts
// stores/types/index.ts
export interface User {
id: number
name: string
email: string
role: 'admin' | 'user'
}
export interface Product {
id: number
name: string
price: number
stock: number
}
export interface CartItem {
productId: number
quantity: number
price: number
}
export interface Order {
id: number
userId: number
items: CartItem[]
total: number
status: 'pending' | 'paid' | 'shipped' | 'completed'
}
Store 内定义类型 #
ts
// stores/user.ts
import { defineStore } from 'pinia'
// 类型定义在 Store 文件内
interface UserState {
user: User | null
token: string | null
}
interface UserGetters {
isAuthenticated: boolean
displayName: string
}
interface UserActions {
login: (email: string, password: string) => Promise<boolean>
logout: () => void
}
export const useUserStore = defineStore('user', {
// ...
})
命名规范 #
Store 命名 #
ts
// 推荐:使用 use 前缀
export const useUserStore = defineStore('user', { /* ... */ })
export const useCartStore = defineStore('cart', { /* ... */ })
export const useProductStore = defineStore('product', { /* ... */ })
// 文件名使用小写
// stores/user.ts
// stores/cart.ts
// stores/product.ts
State 属性命名 #
ts
export const useUserStore = defineStore('user', {
state: () => ({
// 使用清晰的命名
user: null,
isLoading: false, // 布尔值使用 is/has 前缀
hasError: false,
errorMessage: null, // 错误相关使用 error 前缀
// 列表使用复数
users: [],
orders: [],
// 当前选中项使用 current 前缀
currentUser: null,
selectedProduct: null
})
})
Actions 命名 #
ts
export const useUserStore = defineStore('user', {
actions: {
// 获取数据使用 fetch/get
async fetchUser() { /* ... */ },
async getUsers() { /* ... */ },
// 创建使用 create/add
async createUser() { /* ... */ },
addItem() { /* ... */ },
// 更新使用 update/set
async updateUser() { /* ... */ },
setTheme() { /* ... */ },
// 删除使用 delete/remove
async deleteUser() { /* ... */ },
removeItem() { /* ... */ },
// 重置使用 reset/clear
resetState() { /* ... */ },
clearCart() { /* ... */ }
}
})
完整示例 #
电商应用结构 #
text
src/
├── stores/
│ ├── index.ts
│ ├── types/
│ │ ├── user.ts
│ │ ├── product.ts
│ │ ├── cart.ts
│ │ └── order.ts
│ ├── auth/
│ │ ├── index.ts
│ │ ├── user.ts
│ │ └── session.ts
│ ├── shop/
│ │ ├── index.ts
│ │ ├── cart.ts
│ │ ├── product.ts
│ │ └── order.ts
│ └── shared/
│ ├── theme.ts
│ ├── locale.ts
│ └── notification.ts
├── composables/
│ ├── useAsync.ts
│ ├── usePagination.ts
│ └── useForm.ts
├── api/
│ ├── index.ts
│ ├── auth.ts
│ ├── product.ts
│ └── order.ts
└── main.ts
ts
// stores/index.ts
import { createPinia } from 'pinia'
export const pinia = createPinia()
// Auth
export * from './auth'
// Shop
export * from './shop'
// Shared
export * from './shared'
// Types
export * from './types'
最佳实践 #
1. 保持 Store 独立 #
每个 Store 只负责一个领域:
ts
// 好的做法
useUserStore() // 用户相关
useCartStore() // 购物车相关
useOrderStore() // 订单相关
// 不好的做法
useDataStore() // 所有数据混在一起
2. 避免过度拆分 #
ts
// 好的做法:相关状态放在一起
export const useUserStore = defineStore('user', {
state: () => ({
profile: null,
preferences: null,
settings: null
})
})
// 过度拆分
export const useUserProfileStore = defineStore('userProfile', { /* ... */ })
export const useUserPreferencesStore = defineStore('userPreferences', { /* ... */ })
export const useUserSettingsStore = defineStore('userSettings', { /* ... */ })
3. 使用 TypeScript #
ts
// 定义完整的类型
interface UserState {
user: User | null
loading: boolean
error: string | null
}
export const useUserStore = defineStore('user', {
state: (): UserState => ({
user: null,
loading: false,
error: null
})
})
4. 文档注释 #
ts
/**
* 用户状态管理
* @module stores/user
*/
/**
* 用户 Store
* 管理用户登录状态、用户信息等
*/
export const useUserStore = defineStore('user', {
state: () => ({
/** 当前登录用户 */
user: null as User | null,
/** 认证令牌 */
token: null as string | null
})
})
下一步 #
现在你已经掌握了项目结构的组织方式,接下来让我们学习 TypeScript 集成。
- TypeScript集成 - TypeScript 最佳实践
最后更新:2026-03-28