Pinia Store 實作模式
在多品牌平台專案中,使用 Options API 和 Composition API 兩種寫法實作 Pinia Store,根據場景選擇合適的模式。
1. 面試回答主軸
- 兩種寫法:Options API 和 Composition API,根據場景選擇。
- 選擇策略:簡單 Store 用 Composition API,需持久化的用 Options API,複雜邏輯用 Composition API。
- 關鍵差異:State 必 須是函數、Actions 中
this指向 store、Getters 的兩種寫法。
2. Options API(傳統寫法)
2.1 基本結構
import { defineStore } from 'pinia';
import type * as Response from 'src/api/response.type';
import { computed } from 'vue';
type State = Response.login & {
onBoarding: boolean;
totpStatus: Response.GetTotpStatus;
};
export const useAuthStore = defineStore('authStore', {
// 1️⃣ State: 定義狀態
state: (): Partial<State> => ({
access_token: undefined,
agent_id: undefined,
user_id: undefined,
onBoarding: false,
totpStatus: undefined,
}),
// 2️⃣ Actions: 定義方法
actions: {
setTotpStatus(data: Response.GetTotpStatus) {
this.totpStatus = data;
},
setToptVerified(status: boolean) {
this.toptVerified = status;
},
},
// 3️⃣ Getters: 定義計算屬性
getters: {
isLogin: (state) => !!state.access_token,
isOnBoarding: (state) => computed(() => state.onBoarding ?? false),
isToptEnabled: (state) =>
computed(() => state.totpStatus?.is_enabled ?? false),
},
// 4️⃣ 持久化配置
persist: true, // 自動持久化到 localStorage
});
2.2 關鍵重點
1. State 必須是函數
// ✅ 正確
state: () => ({ count: 0 });
// ❌ 錯誤(會導致多個實例共享狀態)
state: {
count: 0;
}
2. Actions 中的 this 指向 store 實例
actions: {
increment() {
this.count++; // 直接修改 state
},
};
3. Getters 的兩種寫法
getters: {
// 方式一:直接返回值(推薦)
doubleCount: (state) => state.count * 2,
// 方式二:返回 computed(響應式更新)
tripleCount: (state) => computed(() => state.count * 3),
};