今回達成すること
nuxt-typed-vuexのインストールとセットアップを行います。
そしてVuexストアの値をVueファイルから呼び出し、挙動や使い方を学びます。
最初にブランチを切っておきましょう。
% git checkout -b 20220109_setup_nuxt_typed_vuex
% git branch
* 20220109_setup_nuxt_typed_vuex
nuxt-typed-vuexをインストールする
nuxt-typed-vuexをインストールします。
% yarn add nuxt-typed-vuex
Vuexをラップしたモジュールなのでdependenciesにインストールします。
今回はv0.2.0を使用します。
% yarn list --pattern nuxt-typed-vuex
└─ nuxt-typed-vuex@0.2.0
buildModulesに登録します。
nuxt.config.js
export default {
buildModules: [
// https://typed-vuex.roe.dev
'nuxt-typed-vuex'
],
}
Vuexファイルを作成する
Vuexを扱うファイルを作成します。
storeディレクトリ直下に
% touch store/index.ts
nuxt-typed-vuexを使ったVuexの基本構文
作成した
store/index.ts
// typed-vuex setup: https://typed-vuex.roe.dev/getting-started/getting-started-nuxt
import { getAccessorType, getterTree, mutationTree, actionTree } from 'typed-vuex'
export const state = () => ({
/* state */
})
export const getters = getterTree(state, {
/* getter */
})
export const mutations = mutationTree(state, {
/* mutation */
})
export const actions = actionTree({ state, getters, mutations }, {
/* action */
})
getterTree、mutationTree、actionTreeがnuxt-typed-vuexの構文となります。
この中に関数を記述することで、自動でVuexストアの型定義を返してくれます。
Vuexストアの型をエクスポートする
型定義をgetAccessorTypeでコンパイルし、型宣言ファイルへエクスポートします。
store/index.ts
export const actions = actionTree({ state, getters, mutations }, {
/* action */
})
// 一番下に追加
export const accessorType = getAccessorType({
state,
getters,
mutations,
actions,
modules: {
/* sub modules */
}
})
modules: {}とは
modules: {}には、
例えばmodules: {} 内は以下のように書きます。
store/index.ts(例)
import * as post from '~/store/post'
export const accessorType = getAccessorType({
modules: {
post
}
})
module.d.tsファイルを作成する
型宣言ファイルを作成します。
モジュールの型宣言ファイルとして、プロジェクトディレクトリ直下に
nuxt-typed-vuex以外にも、アプリ全体で使用するグローバルなモジュールの型定義ファイルとします。
これは独自ルールなので、ディレクトリパスやファイル名は管理しやすいように変更してOKです。
% mkdir types && touch $_/module.d.ts
interface Vueと、interface NuxtAppOptionsにVuexストアの型を追加します。
types/module.d.ts
import { accessorType } from '~/store'
/*
nuxt-typed-vuexの型定義をVueとNuxtに登録
Doc: https://typed-vuex.roe.dev/getting-started/getting-started-nuxt#creating-type-definitions
*/
declare module 'vue/types/vue' {
interface Vue {
$accessor: typeof accessorType
}
}
declare module '@nuxt/types' {
interface NuxtAppOptions {
$accessor: typeof accessorType
}
}
-
declare... 宣誓の意味を持つ。この型のモジュールをエクスポートすることを誓います。ということ。
これでnuxt-typed-vuexが使用できるようになりました。
Vuexストアは$storeではなく$accessorを使用する
nuxt-typed-vuex を使用したVuexは、$accessor で呼び出します。
$storeで呼び出しするとTypeエラーになるので注意してください。
コンテキスト $accessorの格納場所
Nuxtコンテキストには、appプロパティ以下に$accessorが格納されています。
Vueファイル
@Component
export default class IndexPage extends Vue {
asyncData ({ app: { $accessor } }) {
const hoge = $accessor.hoge
}
}
nuxt-typed-vuexの型定義
それではnuxt-typed-vuexがどのような挙動をするか学びましょう。
stateの型付け
state内のデータの型付けにはasを使用します。
state全体の型を使用する場合は、ReturnType<typeof state>で型定義を行います。
store/index.ts
export const state = () => ({
count: 0 as number
})
type RootState = ReturnType<typeof state>
gettersの型付け
gettersは、returnの値によって自動で型定義を行います。
下記コードは number |'カウントゼロ' の型が定義されます。
store/index.ts
export const getters = getterTree(state, {
countValue: (state: RootState, _getters) => (
state.count || 'カウントゼロ'
)
})
mutationsの型付け
mutationsの戻り値はvoid型が定義されます。
引数に渡すpayloadは自分で型を定義します。
store/index.ts
export const mutations = mutationTree(state, {
setCount (state: RootState, payload: number) {
state.count += payload
}
})
エディタで解析された型定義

actionsの型付け
actionsの戻り値はvoid型が定義されます。
この型は自ら定義することも可能です。
メソッドの引数(value: number)には自ら型を定義を行います。
store/index.ts
export const actions = actionTree({ state, getters, mutations }, {
countUp ({ commit }, value: number) {
commit('setCount', value)
}
})
{ commit }などのコンテキストの型は、nuxt-typed-vuexがActionContextとして自動で型定義してくれます。
下画像を見て分かる通り、ActionContextには state、getters、mutations の型が定義されています。
これはactionTree()に渡したstate、getters、mutations を解析し型定義を行なっています。
エディタで解析された型定義

例えばgetters.countValueをArray型に代入しようとするとエラーとなります。
これはアクションメソッドのコンテキストの型が正しく定義されている証拠です。
export const actions = actionTree({ state, getters, mutations }, {
countUp ({ commit, getters }, value: number) {
/*
Type Error
Type 'number | "カウントゼロ"' is not assignable to type '[]'.
Type 'number' is not assignable to type '[]'.
*/
const count: [] = getters.countValue
}
})
VueファイルからのVuexを呼び出そう
Vuexストアで宣言した値と関数を
pages/index.vue
<template>
<div>
<v-container>
<!-- v-container直下に追加 -->
<v-card>
<v-card-title>
nuxt-typed-vuexのテスト
</v-card-title>
<v-card-text>
state.count: {{ $accessor.count }}<br>
getters:countValue: {{ $accessor.countValue }}
</v-card-text>
<v-card-actions>
<v-btn
@click="$accessor.countUp(1)"
>
count up
</v-btn>
</v-card-actions>
</v-card>
<!-- ここまで -->
</template>
ブラウザにVuexストアの値が表示されました。
COUNT UPボタンでStateの値が増えていることも確認してください。

stateやactionメソッドは$accessor直下に紐づく
従来のVuexと大きく変わる点は、state、getters、mutations、acrionsで宣言したデータや関数は、全て$accessor 直下のプロパティに追加されます。
console.log(this.$accessor)
$accessor: {
count: (...)
countValue: (...)
setCount: ƒ (mutationPayload)
countUp: ƒ (actionPayload)
}
サブモジュールは$accessor.<プロパティ名>で呼び出す
store/index.ts(例)
import * as post from '~/store/post'
export const accessorType = getAccessorType({
modules: {
// 呼び出しプロパティ名
post
}
})
この時modulesで指定したプロパティ名で呼び出します。
pages/inde.vue(例)
<div>
{{ $accessor.post.<State or function> }}
</div>
それではコミットして作業を終わります。
% git add -A
% git commit -m "Add module nuxt-typed-vuex and initial settings"
次回は?
今回はnuxt-typed-vuexのインストールとセットアップ、挙動とVuexの扱い方を学びました。
次回は、VuexにContentfulのAPIデータの型定義やStateの用意を行います。