Pinia 最佳实践与常见错误
在多品牌平台项目中,Pinia Store 的最佳实践与常见错误处理。
1. 面试回答主轴
- 设计原则:单一职责原则、保持 Store 精简、避免在 Store 中直接调用 API。
- 常见错误:直接解构失去响应性、在 Setup 外部调用 Store、修改 State 破坏响应性、循环依赖。
- 最佳实践:使用 TypeScript、职责分离、在 Composable 中组合多个 Store。
2. Store 设计原则
2.1 单一职责原则
// ✅ 好的设计:每个 Store 只负责一个领域
useAuthStore(); // 只管认证
useUserInfoStore(); // 只管用户信息
useGameStore(); // 只管游戏信息
// ❌ 坏的设计:一个 Store 管理所有东西
useAppStore(); // 管理认证、用户、游戏、设定...
2.2 保持 Store 精简
// ✅ 推荐
export const useBannerStore = defineStore('bannerStore', () => {
const bannerState = reactive({ list: [] });
function setStoreBannerList(list: Response.BannerList) {
bannerState.list = list;
}
return { bannerState, setStoreBannerList };
});
// ❌ 不推荐:Store 中包含复杂的业务逻辑
// 应该放在 composable 中
2.3 避免在 Store 中直接调用 API
// ❌ 不推荐:在 Store 中直接调用 API
export const useGameStore = defineStore('gameStore', {
actions: {
async fetchGames() {
const data = await api.getGames(); // API 调用
this.list = data;
},
},
});
// ✅ 推荐:在 Composable 中调用 API,Store 只负责存储
export const useGameStore = defineStore('gameStore', {
actions: {
setGameList(list: Game[]) {
this.list = list;
},
},
});
export function useGame() {
const gameStore = useGameStore();
async function fetchGames() {
const { status, data } = await api.getGames(); // Composable 中调用 API
if (status) {
gameStore.setGameList(data); // Store 只负责存储
}
}
return { fetchGames };
}
3. 使用 TypeScript
// ✅ 完整的类型定义
type UserState = {
info: Response.UserInfo;
walletList: Response.UserWalletList;
};
export const useUserInfoStore = defineStore('useInfoStore', () => {
const state = reactive<UserState>({
info: {} as Response.UserInfo,
walletList: [],
});
return { state };
});
4. 常见错误
4.1 错误 1:直接解构导致响应性丢失
// ❌ 错误
const { count } = useCounterStore();
count; // 不是响应式的
// ✅ 正确
const { count } = storeToRefs(useCounterStore());
count.value; // 响应式的
4.2 错误 2:在 Setup 外部调用 Store
// ❌ 错误:在模块顶层调用
const authStore = useAuthStore(); // ❌ 错误时机
export function useAuth() {
return {
isLogin: authStore.isLogin,
};
}
// ✅ 正确:在函数内部调用
export function useAuth() {
const authStore = useAuthStore(); // ✅ 正确时机
return {
isLogin: authStore.isLogin,
};
}