Nuxt.jsの基本的な使い方【storeを使ったデータの状態管理編】

# プロローグ

Nuxt.jsを触り始めて三ヶ月弱くらいですが、
色々と使い方を覚えてきたので、メモとして記録を残します。

不備不足だったり、理解が浅くて説明不足なところがあるかと思いますが、
勉強して更新していきたいとは思っています。

# この記事で何ができるようになるか

storeを使ってデータを扱うにはこうするんだ〜程度のことがわかるようになるかとは思います。
というのも、まだ１回教えてもらってなんとか使えるようになった程度なので、詰めが甘いところがあるかと思います。

# storeとは

storeを使うことで、アプリケーションの状態(state)やデータを保持することができます。
emitやpropを使ってdataを共有することもできますが、ブラウザ上にデータを保持することがストアではできるので、一旦ブラウザを閉じてもstoreに保持したデータは残ります。

# 使い方

今回はクラシックモードでストアを使うので、Vuex インスタンスを返す関数がエクスポートされている store/index.js ファイルを作ります。
しかし、この機能（クラシックモード）は Nuxt 3 で廃止し、削除される予定です・・。

>クラシックモード
>この機能は Nuxt 3 で廃止し、削除される予定です。

>クラシックモードでストアを使うには、Vuex インスタンスを返す関数がエクスポートされている >store/index.js ファイルを作る必要があります。

参照：[Nuxt.jsドキュメント Vuexストア](https://develop365.gitlab.io/nuxtjs-2.8.X-doc/ja/#vuex-strict-%E3%83%A2%E3%83%BC%E3%83%89)

## store/index.jsを解説

保持されたデータを扱うために、下記の４つを使ってデータを扱います。
リンク先はそれぞれのドキュメントに記載されている説明になります。

| 用語 |  | 
|:-----------|:-----------|
| [state](https://vuex.vuejs.org/ja/guide/state.html#%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88)       | データの情報源（信頼できる唯一の情報源 ） | 
| [getter](https://vuex.vuejs.org/ja/guide/getters.html#%E3%82%B1%E3%82%99%E3%83%83%E3%82%BF%E3%83%BC)| 変更された値を保持する（ゲッターの結果はその依存関係に基づいて計算され、依存関係の一部が変更されたときにのみ再評価される ） | 
| [mutation](https://vuex.vuejs.org/ja/guide/mutations.html#%E3%83%9F%E3%83%A5%E3%83%BC%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3) | データの情報源を更新する（実際に状態の変更を行う） | 
| [action](https://vuex.vuejs.org/ja/guide/actions.html#%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3) | *非同期処理や外部APIとの通信を行い、最終的にmutationを呼び出す為に使われます。*（引用：[【Vuex】ストアの4つの概念まとめ【唯一の情報源】](https://qiita.com/kouki-iwahara/items/1a75daaa93657b0b56d7#action)） | 

今回は、state / mutation / actionを解説していきたいと思います（getterはまだ使ったことないので割愛させていただきます）。

今回保持したいデータとして、ブログなどで月別での記事を検索するとします。
下記画像のように、「４月」をクリックしたら「４月」の記事一覧画面へ遷移するとともに、「４月」というデータを保持したい場合を想定します。

![スクリーンショット 2021-05-02 19.52.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/04ab9019-df53-9830-110a-729b93d61437.png)

「４月」の記事一覧画面へ遷移すると同時に、選択された「４月」というデータを保持する。

![スクリーンショット 2021-05-02 19.53.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/3d48d596-2a89-e157-1754-d12f307d986f.png)

store/index.jsでの解説を行っていきます（コメントにて説明）。

```JavaScript:store/index.js

export const state = () => ({
  selectedDay: null
});
//stateでデータを設定します。月別での記事を検索する前は月は選ばれていないのでnullと設定しました。

export const mutations = {
  setSelectedDay(state, selectedDay) {
    state.selectedDay = selectedDay
  }
}
//setSelectedDay(state, selectedDay) の第1引数で状態（state）を取得します。
//第2引数でselectedDayの値をstate（情報源）に渡します。ここでは例えばselectedDayを４月とします。
//すると、setSelectedDay(state, selectedDay) {}の中身では
//selectedDayがnullだったものを４月とデータを更新していることになります（state.selectedDay = selectedDayがそれ）。

export const actions = {
  setSelectedDay({ commit }, selectedDay) {
    commit('setSelectedDay', selectedDay)
  }
//setSelectedDay({ commit }, selectedDay)の第1引数でmutationsとcommitします。
//Actions は、状態は変更せず、 Mutations を commitし、Mutations を commit することで状態(State)を更新します。：引用（参考記事/[Vue.js] Vuexの使い方を知る）
//commit('setSelectedDay', selectedDay)では、第１引数に呼び出す関数の名前を入れてます。
//第２引数では該当mutationsで使用する値（selectedDay）をいれています。
}

```
`actions`で非同期処理や外部APIとの通信を行い変更されたデータが`setSelectedDay`に入ります。
`setSelectedDay`に入ったデータは`mutations`の`state.selectedDay = selectedDay`で更新されます。
更新されたデータは`state`の`selectedDay`に保持されてるというながれになります。

`actions`（データ受け取り） -> `mutations`（データ更新） -> `state`（データ保持）
という流れになります。

## pages/index.vueを解説

保持されたデータを使いたいときは下記のように書きます。
こうすることで、保持されたデータが`day`に入ったので、使い回すことができます。

```Javascript:index.vue

const day = this.$store.state.selectedDay

```

stateのデータを更新したいときは下記のように書きます。
('setSelectedDate', "５月")の第１引数はactionsで定義した関数の名前です。
第２引数は更新したい値をいれます。

```Javascript:index.vue

this.$store.dispatch('setSelectedDate', "５月")
//または
this.$store.dispatch('setSelectedDate', this.lastDay)
//dataで定めた値を入れてもいい

```

# おまけ

説明してきたように、vueでstoreの状態を呼び出したり（`this.$store.state.selectedDay`）、更新させたり（`this.$store.dispatch('setSelectedDate', this.lastDay)`）することができます。

そのときに便利なヘルパーがあるのでそちらの記事を引用して終わりにします。

・[【Vuex】mapState, mapGetters, mapMutations, mapActionsの最低限の使い方まとめ](https://qiita.com/terufumi1122/items/6f9470c8d416a4af7502)



# 参考記事
・[Vuexとは。まずはこれを読んでVuexの概要を理解しよう。](https://dev83.com/vue-vuex/)
・[Nuxt.jsをはじめよう - Vuexを使ってデータを渡す](https://www.soudegesu.com/post/javascript/store-with-nuxt/)
・[Vue.js、Nuxt.jsでのVuex(store)の使いドコロ](https://beginner-enginner.netlify.app/vuex-use-case/)
・[Nuxt.js で Vuex を使う](https://blog.mintsu-dev.com/posts/2019-04-21-nuxt-vuex/#vuex-%E3%81%A8%E3%81%AF%E3%81%AA%E3%81%AB%E3%81%8B)
・[【Vuex】ストアの4つの概念まとめ【唯一の情報源】](https://qiita.com/kouki-iwahara/items/1a75daaa93657b0b56d7)
・[[Vue.js] Vuexの使い方を知る](https://b.0218.jp/20190815134715.html)


### 一言

数週間前にやったものですが、１度書いてみただけだったので、記事を書くにあたって調べ直したり、理解が浅すぎるところがありました・・。何回も何回も同じ状態に遭遇して、やらないと覚えきれないなと痛感しました。

なので、再度不備不足や間違っているところがないのかを勉強し直して更新していきます。