useXXXStore
(moduleごとの composable)の作り方(Vuex module構成 × Composition API × TypeScript)
Vuex module を namespaced: true
で分けたら、
moduleごとに useXxxStore()
を作るとアクセスが簡単&型安全
state
, getters
, mutations
, actions
のアクセスも 補完付きで楽になる
module名を毎回 "user/login"
みたいに書かなくて済む
→ useUserStore()
みたいな関数で、「そのmodule専用のstoreアクセス」を渡す設計
会社には「営業部」「開発部」などがある。
本部(root store)に毎回「営業部に回してください」と言わなくても、
直接「営業部直通窓口(
useUserStore
)」があると楽。「部署ごとの担当窓口」を作るイメージ。
src/
├ store/
│ ├ index.ts ← root store
│ ├ types.ts ← ルート型
│ ├ modules/
│ │ └ user.ts ← user module
│ ├ composables/
│ │ └ useUserStore.ts ← user module用 useStore
useUserStore
の作成// store/composables/useUserStore.ts
import { useStore as baseUseStore } from 'vuex';
import { Store } from 'vuex';
import { RootState } from '../types';
import { UserMutationTypes, UserActionTypes } from '../modules/user';
// 型付きuseStore
export const useUserStore = () => {
const store = baseUseStore<RootState>();
return {
// stateへのアクセス
userName: store.state.user.userName,
isLoggedIn: store.state.user.isLoggedIn,
// gettersへのアクセス
isUserLoggedIn: store.getters['user/isLoggedIn'] as boolean,
// mutationを型付きで呼び出す
setUserName: (name: string) => {
store.commit(`user/${UserMutationTypes.SetUserName}`, name);
},
// actionを型付きで呼び出す
login: (name: string) => {
return store.dispatch(`user/${UserActionTypes.Login}`, name) as Promise<boolean>;
}
};
};