TypeScript で Vuex を使う + localStorage で永続化する
Nuxt.js + TypeScript + Vuex + vuex-persistedstate でがんばる。
すること
- Nuxt.js で
- TypeScript 環境で
- Vuex で状態管理して
- vuex-persistedstate を使って localStorage に状態を永続保持させる。
環境
- Node.js: v16.12.0
-
nuxt
: v2.15.8 -
nuxt-typed-vuex
: v0.3.1 -
vuex-persistedstate
: v4.1.0
本記事では、以下のリポジトリで作業しています。
- GitHub Pages: https://book000.github.io/vuex-ts/
方法
作業内容を大きく以下の 3 つに分割します。
- TypeScript 環境で Nuxt.js プロジェクトを作成する
- Vuex を TypeScript サポートさせる (
nuxt-typed-vuex
) - Vuex の「状態」を localStorage に保存するように設定する (
vuex-persistedstate
)
TypeScript 環境で Nuxt.js プロジェクトを作成する
この記事では、超簡単なインクリメントしかしないカウンタを作ります。
yarn create nuxt-app
(Npm であれば npx create-nuxt-app
)を用いて Nuxt.js のプロジェクトを作成します。
ここでやることは簡単です。Programming language
の選択肢で TypeScript
を選んでください。
Vuex を TypeScript サポートさせる
nuxt-typed-vuex
を用いて、Vuex を Typed な Vuex にします。
まず、nuxt-typed-vuex
を依存関係に追加します。
yarn add nuxt-typed-vuex
次に、nuxt.config.js
(TypeScript 化している場合は nuxt.config.ts
)を編集します。
buildModules
に先ほど依存関係に追加した nuxt-typed-vuex
を追加してください。
-buildModules: ["@nuxt/typescript-build", "@nuxtjs/vuetify"],
+buildModules: ["@nuxt/typescript-build", "@nuxtjs/vuetify", "nuxt-typed-vuex"],
さらに、store/index.ts
を作成します。
カウンタの状態管理ストアを作るため、store/counter.ts
を作成します。
これ以外にストアを作成する場合は、適宜 store/index.ts
の getAccessorType
にある modules
に追加してください。
最後に、型推論してもらうためには、$accessor
でアクセスする必要があります。適当なところに d.ts を作成しておきましょう。
{
"compilerOptions": {
+ "typeRoots": ["types"]
}
}
$accessor.counter.count
で取得、$accessor.counter.setCount
で変更できます。
Vue.js devtools を用いて Vuex を覗いてみると、きちんと記録されていることが確認できます。
Vuex の「状態」を localStorage に保存するように設定する
vuex-persistedstate
を用いて、Vuex の中身を localStorage に自動保存・復元するようにします。
まず、vuex-persistedstate
を依存関係に追加します。
yarn add vuex-persistedstate
次に、plugins/counter.ts
を作成して先ほどの counter
を localStorage に保存してもらうように設定します。
最後に、nuxt.config.js
(TypeScript 化している場合は nuxt.config.ts
)を編集します。先ほど作成した plugins/counter.ts
を読み込むように設定します。
- plugins: [],
+ plugins: [{ src: "~/plugins/counter", ssr: false }],
count
を変更させてみたあと、再読み込みしてもきちんと数値が復元されることを確認できたら成功です。
参考
この記事は以下の 2 つを組み合わせてできあがっています。ありがとうございます。
Discussion