【Vue,Vuex】storeファイルを分割して使用する

**内容**：vuexのactions, mutations, stateをそれぞれ分割したファイルにする

**書いた理由**：これが一番慣れるまでに時間がかかったので理解できているか、色んな人にこの記事を読んでもらって確かめるため


ストア管理の大変さは下記記事で紹介されています。
[Vuex StoreのModule分割](https://qiita.com/yuzgit/items/7cd813e614e97507171e)
今回はこの記事も参考にしながらさらに細かく分割していきます。
- src\store\modulesの中にページ毎にストアファイルを作る場合（例えば管理者とユーザーで異なる画面表示をする際や、処理内容などを分けて作る場合など）
```
構成
src
 └─store
    └─modules
　  │ 　│─foo
    │   │   └─top //例:トップページ
    │   │     ├─actions.js
    │   │     ├─mutations.js
    │   │     ├─state.js
    │   │     └─index.js（③）
    │   │    
    │   └─index.js（②） // topの読み込み
    │
　  └─index.js（①） // fooの読み込み  
```
index.jsが３つあるので①-③としました。


-----------------------
**index.js①-③の解説**
①：fooの読み込みです
``` js:src\store\index.js
import foo from './modules/foo'

export default new Vuex.Store({
    modules: {
        //modeuls内のfoo
        ...foo, 
        //以下他のmodules,
    },
});
```
②：topの読み込み
```js:src\store\modules\foo\index.js
import top from './top'
export default {
    top,
}
```
③：各ストアファイルの読み込み
```js:src\store\modules\foo\top\index.js
import state from './state'
import * as mutations from './mutations'
import * as actions from './actions'

export default {
  namespaced: true,
  mutations,
  actions,
  state
}
```
以上が各index.jsの説明です。

--------------------------

次は、分割した後どのようにアクションズなどを呼び出すのかの説明です。


index.js②によってコンポーネントから楽にアクションズなどを呼ぶことが出来ます。
例:[クリックしたら送信](https://ja.vuejs.org/guide/essentials/event-handling.html)
```vue:main.vue　'dispatch'の後に注目
//@click="onSubmit"  他省略
<script>
    const page_name = "top";

    export default {
      methods: {
         async onSubmit() {
               //validationなどの処理を記載、その後にsubmit      
            const res = await this.$store.dispatch(`${page_name}/submit`); 

            if(res) { 
                //apiのレスポンスがあれば・・・などの処理などの記載も可能 
            }
          }  
      };  
    };
</script>

```

この後dispatchで呼ばれたactionsに行きます。
```js:action.js
import axios from 'axios'
export async function submit () {
  formData.append(sample, sample) //dataとして渡したいもの
  const response = await axios({
    method: 'post',
    url: "/submit", // api.phpなりルーティングで設定したurl
    data: formData
  }).then(res => {
    //return res　レスポンスを返したり
  }).catch(err => {
    //エラー内容を返したり
    console.log("エラー", err);
    return null
  })
}
```
もし上記処理内でcommitしたい場合やstateを使用する際は下記のように書いてください。
``function submit ({commit, state})``

**メインの内容おわり**
以下、おまけ。mitations.jsやstate.jsの使用方法をサラッとだけ書いています。


---------------------
**[commitする場合](https://qiita.com/aki4003/items/d34c4096f8f2b61d4dfb)**
上記処理内に
``await commit('sample')``のような感じで使用したいタイミングの場所に記載してください。
第二引数を指定する場合は下記のように書くことが出来ます。
``await commit('sample', {hoge, fuga})``

これはmutations.jsへ行きます。
```js:mutations.js
export function sample(state) {
    state.sample = sample;
  }
```
このように記載可能です。この時、第二引数の指定ももちろん可能です。
mutations.jsからstate.jsに渡しているので、state.jsを使用できるように下記のように指定しましょう！
```js:state.js
export default function() {
    return {
         sample: '', //例
    }
}
```
これでコンポーネント側からこの``state.sample``にアクセス可能になります。


--------------------------------
APIから値を取得してVueコンポーネントに描画したい場合などに3コンボ、と勝手に呼んでます（actions→mutations→state）を使用するのが多いかと思います。

例えばLaravel+Vueで、サイトの画面を開いた際にそのユーザーが持っている情報をすぐ取り出せるようにしておく場面などです。

1.Vue：dispatchでactions.js内に飛ばす
2.actions内でLaravel側の情報一覧を返す処理を呼ぶ
3.actionsにresponseとして持つ、mutationsへ
4.mutationsからstateに管理させる
5.state.js内で管理しているデータをVueで描画
でしょうか。

**おわり**

----------------------------------------------------------------------

参考:tiger: 
- [公式ドキュメント](https://vuex.vuejs.org/ja/)
- [Vuexの使い方や責務について](https://zenn.dev/chida/articles/e455b5139f00cc)
- [Vuex, store の設定と state の参照](https://uncle-javascript.com/when-vuex-and-store-settings)