Vuexについての備忘録

Vuexについて勉強をしたので、備忘録としてまとめる。

## Vuexとは？
Vuexとは、Vueアプリケーションで使用する状態管理ライブラリ。アプリケーションで扱うデータセットを storeと呼ばれる領域で一元管理することで、各コンポーネントは Store にアクセスすれば常に共通の値を参照することができるようになる。

# store
- 様々なコンポーネントを共通して扱える「store」と呼ばれる保管場所を提供する
- 「store」フォルダにスクリプトを用意する必要がある。
- Vuexを使うためには、Vuex.Storeを生成することが必要。コンポーネント のdataと同じように関数として値を用意
- 「state」はコンポーネントのdataに相当するようなイメージ
- storeの作成時に定義できる項目は「state」「getters」「mutations」「actions」

```
const store new Vuex.Store({
  state: { ... },
  getters: { ... },
  mutations: { ... },
  actions: { ... }
});
```

## state
- Vuexのstoreで管理するデータ項目を定義
- ここに定義したデータは Vueアプリケーション内の各コンポーネントから適宜取得・更新することができる。

例

```
//  Store 定義
const store = new Vuex.Store({
  state: {
    count: 0
  }
});

export default store;
```

#### コンポーネントからstateの値を利用
- コンポーネントからは、this.$store.stateを経由して値を参照できる

```
<template>
  <div>{{ count }}</div>
</template>

<script>
export default {
  name: "Counter",
  computed: {
    count () {
      return this.$store.state.count
    }
  }
};
</script>
```

#### stateデータの更新・削除について 
- stateはthis.$store.state.count = 100のように直接更新・削除を行ってはいけない
- 基本的に Store 内のデータに対する操作は、後述する mutations に定義する。

## mutation
- ストアにあるステートを変更したい場合は、値の操作を行う処理をストア側に用意する

```
mutation: {
  名前: function (実数){ }
  --略--
},
```
ミューテーションは、「commit」というメソッドを利用する。

```
{{ $store.commit( 名前 )}}
```
- 引数には、実行するミューテーションの名前を指定
- 指定されたミューテーションの実行がストア側に送られ、ストアの更新などが行われる

```
const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 状態を変更する
      state.count++
    }
  }
})
```
```
store.commit('increment')
```

#### mutationsに引数を渡す場合

```
mutations: {
  count: function(state, n) {
    state.counter += n;
  },
  reset: function(state) {
    state.counter = 0;
  }
}
```
- 引数にはstateが自動的に渡される
- 独自に引数（上記だとn）を渡すことができる

```
<template>
  <section class="container">
    <h1>{{ title }}</h1>
    <p>{{ $store.state.message }}</p>
    <hr>
    <div class="link"
      @click="$store.commit('count', 1)"
      @click.shift="$store.commit('count', 2)"
      @click.ctrl="$store.commit('count', 3)"
      >{{ $store.state.counter }}</div>
    <router-link to="/other">Go to Other</router-link>
  </section>
</template>
```

#### 1つだけでなく、たくさんの引数を用意する場合
- 必要な値を1つのオブジェクトにまとめて引数として渡す

```
mutations: {
  count: function(state, obj) {
    state.message = obj.message;
    state.counter += obj.add;
  },
  reset: function(state) {
    state.counter = 0;
  }
}
```
```
<template>
  <section class="container">
    <h1>{{ title }}</h1>
    <p>{{ $store.state.message }}</p>
    <hr>
    <div class="link"
      @click.exact="$store.commit({type: 'count', message:'add 1',  add: 1})"
      >{{ $store.state.counter }}</div>
    <router-link to="/other">Go to Other</router-link>
  </section>
</template>
```

## actions
- ミューテーションを実行するための仕組み
- 複数のミューテーションを続けて呼び出す場合に用いられる
- 書き方はミューテーションとほとんど同じ。名前の後に関数を定義し、そこに処理を記述
- 引数は、第1引数に必ずcontextというオブジェクトが渡されます。
- 「commit」メソッドを使って、ミューテーションを実行できる
- 非同期処理を実行する時もこちらでやる

```
actions:{
  名前: function( 引数 ){
    ....呼び出す処理....
  },
}
```
```
actions: {
      doit: function(context) {
        var n = Math.floor(Math.random() * 10);
        context.commit('count',n);
        context.commit('say', 'add' + n + '!')
      },
    }
```
- dispatchでアクションを呼び出す。

```
<template>
  <section class="container">
    <h1>{{ title }}</h1>
    <p>{{ $store.state.message }}</p>
    <hr>
    <div class="link"
      @click ="$store.dispatch('doit')"
      >{{ $store.state.counter }}</div>
    <router-link to="/other">Go to Other</router-link>
  </section>
</template>
```
##### 値をずっと保持する
- ページをリロードしたら、counterステートの値が初期状態のゼロに戻る
- vuex-persitdstateを使うと、Vuexのステートを、ローカルストレージに保管し、終了後も消えないようにしてくれる.

#### storeモード
- クラシックモード: もっとも基本的な方式。1つのファイル（index.js）の中にすべてのストア関係を記述する

- モジュールモード: より発展的な方式.「store」フォルダの中に複数のファイルを設置し、それぞれにストアの内容を記述する


#### クラシックモードの書き方
- new Vuex.Storeオブジェクトを返す関数を用意し、それをexport defaultする

```
const createStore = () => {
  return new Vuex.store({
    state: function() {
      return { 略 };
    },
    mutations: {
      〇〇: function(state){
        ...略...
      },
      ...略...
    }
  })
}

export default createStore
```

#### モジュールモードの書き方
- Vuex.Storeオブジェクト内に用意するストア関連の情報を、個別にexportしていく
- すべてのストアファイル（「store」フォルダ内に用意するスクリプトファイル）で同じように記述
- 「store」フォルダ内の全てのファイルを読み込み、ストアの内容をまとめて扱えるようになる

```
export const state = () => ({
  ...略...
})

export const mutation = {
  〇〇: function(state){
        ...略...
      },
      ...略...
}
```
- ステートの値は「$store.state.モジュール.〇〇

```
memo: function(){ return this.$store.state.memo.memo }
```

参考図書
Vue.js&Nuxt.js超入門