actions
を await
付きで安全に使うパターン(Composition API × TypeScript × Vuex)
actions
は 非同期処理 (API呼び出しなど) を行う場所await store.dispatch('action名', payload)
の形で呼ぶPromise<戻り値の型>
を正しく返す → await
で受け取るAction = 「ピザください!」
→ 焼くのに30分かかる(非同期)。
→ 焼き上がるまで
await
して待つ。→ 出てくるピザ(戻り値)の型もわかってる。
store/types.ts
// RootState
export interface RootState {
count: number;
userName: string;
}
// mutation名
export const MutationTypes = {
Increment: 'increment',
SetUserName: 'setUserName'
} as const;
// action名
export const ActionTypes = {
UpdateUserName: 'updateUserName'
} as const;
// mutation payloads
export interface MutationPayloads {
[MutationTypes.Increment]: undefined;
[MutationTypes.SetUserName]: string;
}
// action payloads
export interface ActionPayloads {
[ActionTypes.UpdateUserName]: string; // ユーザー名
}
// actionの戻り値の型
export interface ActionReturns {
[ActionTypes.UpdateUserName]: boolean; // 成功したらtrue
}
index.ts
)import Vue from 'vue';
import Vuex, { StoreOptions } from 'vuex';
import { RootState, MutationTypes, ActionTypes, MutationPayloads, ActionPayloads, ActionReturns } from './types';
Vue.use(Vuex);
export const store = new Vuex.Store<RootState>({
state: {
count: 0,
userName: 'Taro'
},
mutations: {
[MutationTypes.Increment](state) {
state.count++;
},
[MutationTypes.SetUserName](state, name: string) {
state.userName = name;
}
},
actions: {
// 戻り値に型をつける(Promise<boolean>)
async [ActionTypes.UpdateUserName]({ commit }, name: ActionPayloads[typeof ActionTypes.UpdateUserName]): Promise<ActionReturns[typeof ActionTypes.UpdateUserName]> {
await new Promise(resolve => setTimeout(resolve, 1000)); // 1秒待つ
commit(MutationTypes.SetUserName, name);
return true; // 成功を返す
}
}
});