Vuexストアを型付けするモジュールの検討
Nuxt × Vuex × TypeScriptを使用するにあたって、Vuexストアに型付けを行うには複数の選択肢があります。
どのようなモジュールがあり、どんな違いがあるかを知って使用する型付けモジュールを決定します。
今回比較するのは以下の2つです。
- クラスベースの
vuex-module-decorators
か - バニラ(従来の書き方)ベースの
nuxt-typed-vuex
か
検討1. vuex-module-decoratorsを使用するか
Vuexストアを型付けするにあたって、最も人気のあるモジュールは vuex-module-decorators です。
vuex-module-decorators
モジュールは、nuxt-property-decorator
にラップされており、いつでも使用できる状態です。
% yarn list --pattern vuex-module-decorators
└─ vuex-module-decorators@1.2.0
vuex-module-decoratorsの書き方
vuex-module-decorators
は、クラスベースで Vuexストアに型付けを行う方法を取ります。
store/mymodule.ts
import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'
@Module({
stateFactory: true,
name: 'mymodule',
namespaced: true
})
export default class MyModule extends VuexModule {
count: number = 0
@Mutation
increment (delta: number) {
this.count += delta
}
@Action({ commit: 'increment' })
incr (delta: number) {
return delta
}
}
store/index.ts
import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import mymodule from './mymodule'
let indexStore: mymodule
function initialiseStores (store: Store<any>): void {
indexStore = getModule(mymodule, store)
}
const initializer = (store: Store<any>) => initialiseStores(store)
export const plugins = [initializer]
export {
initialiseStores,
indexStore
}
見ての通り、TypeScriptを使用しない従来の書き方と大きく違うため、ある程度の学習コストが必要です。
検討2. nuxt-typed-vuexを使用する
対して、従来のVuexの書き方を残したまま型付けしやすいようにVuexをラップした nuxt-typed-vuex というモジュールも存在します。
Vuex はアプリケーションからストアへアクセスするための便利な型を提供していません。
this.$store
は Nuxt アプリケーションで型指定されていないままです。
nuxt-typed-vuex
という新しいプロジェクトがあり(ガイド)、このプロジェクトは素の Nuxt ストアに強く型付けされたアクセサーを提供することで上述の件を改善することを目的としています。
nuxt-typed-vuexの書き方
nuxt-typed-vuex
は、バニラベースでVuexストアに型付けする方法を取ります。
store/index.ts
import { getAccessorType, getterTree, mutationTree, actionTree } from 'typed-vuex'
export const state = () => ({
count: 0 as number
})
export const getters = getterTree(state, {})
export const mutations = mutationTree(state, {
increment (state: RootState, delta: number): void {
state.count = delta
}
})
export const actions = actionTree({ state, getters, mutations }, {
getActiveTocId ({ commit }: { commit: any }, delta: number) {
commit('increment', delta)
}
})
export const accessorType = getAccessorType({
state,
getters,
mutations,
actions,
modules: {
/* store module */
}
})
nuxt-typed-vuex
は v0.2.0(2022年1月現在)とまだ新しいモジュールですが、今まで純粋なVuexを使用してきた方には、直感的に型付けが行えるコード設計となっています。
また、上記引用を見ても公式(Nuxt TypeScript)で紹介されているモジュールなので、ある程度の信頼はできるでしょう。(これは肌感)
結論 nuxt-typed-vuexを使用する
今回はできるだけ学習コストを抑えたnuxt-typed-vuex
を使用します。
本ブログもnuxt-typed-vuex
を使用していますが、v0.2.0でも何の問題も無く使用できていますのでご安心ください。
ちなみに、Nuxt3の移行を見据えたvuex-type-helperを使用する方法もありました。
移行の考え方など、参考になる情報でしたのでここに共有します。
Nuxt3からはVuexがデフォルトでなくなる
Nuxt3 Betaが2021年12月に発表されましたが、Vuexの代わりに状態管理を行うuseStoreという機能が組み込まれました。
またVue3からは、Composition APIを前提としたPiniaという新しい状態管理ライブラリが使用できるようになりました。
この流れを見ると、NuxtからVuexが完全に消える日もそう遠くないかもしれません。
次回は?
上記は筆者の考え方であってvuex-module-decorators
を使用しない方が良い。という意見ではありません。
あくまで好みの問題であり、クラスベースに慣れている方はvuex-module-decorators
の使用を検討してください。
さて次回はnuxt-typed-vuex
のインストールとセットアップを行います。