初心者がVuexの公式ガイドを勉強するメモ コアコンセプト　アクション編

# Vuex コアコンセプト アクション編
## 今回のお題は、こちらです。
### https://vuex.vuejs.org/ja/actions.html

## アクション

* store.js

``` js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 51
  },
  getters: {
  },
  mutations: {
    increment: (state) => {
      state.count ++
    },
    decrement: state => state.count--,
  },
  actions: {
    increment ({ commit, state, getters }) {
      commit('increment')
    }
    // increment (context) {
    //   context.commit('increment')
    // }
  }
})
export default store

store.dispatch('increment')
console.log(store.state.count)

```
* context は、state, getters, commit の大元とのこと。
* actions -> mutations 数珠つなぎになっていますね。
* `{ commit, state, getters }` は, contextを分割代入しています。
  * 分割代入で書いたほうがいいですね。
  * 引数の順番は、ありません。
  * stateも引っ張ってこれますが、ここでの使用はread onlyです。


![actions_1.png](https://qiita-image-store.s3.amazonaws.com/0/131175/83a4a918-c548-a1c3-fd4f-caefe355238e.png)


#### アクションのディスパッチ

* store.js

``` js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 51
  },
  getters: {
  },
  mutations: {
    increment: (state) => {
      state.count ++
    },
    decrement: state => state.count--,
  },
  actions: {
    increment ({ commit, state, getters }) {
      setTimeout( () => {
        commit('increment')
      }, 1000)
    }
  }
})
export default store

store.dispatch('increment')
console.log(store.state.count)
```

* 非同期処理をしたい場合は、mutationsでやらずに、actionsでしなさいとのこと。
* actionsをつかうなら、mutationsは、actionsで加工をしたデータの書き込み処理専用みたいな感じでしょうか。

### オブジェクト形式とペイロード形式

* store.js

``` js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 51
  },
  getters: {
  },
  mutations: {
    increment: (state, n) => {
      state.count = state.count + n
    },
    decrement: state => state.count--,
  },
  actions: {
    increment ({ commit }, { amount }) {
      commit('increment', amount)
      // increment ({ commit }, payload) {
      // commit('increment', payload.amount)
    }
    // increment (context, payload) {
    //     context.commit('increment', payload.amount)
    // }
  }
})
export default store

store.dispatch('increment', {
  amount: 10
})
console.log('store.state.count + 10 :',store.state.count)


store.dispatch({
  type: 'increment',
  amount: 20
})
console.log('store.state.count + 20 :',store.state.count)

```

* payloadも分割代入できますね。
* dispatchも、オブジェクト形式を推奨とのこと。
  * type: を使うかはお好みです。

#### より実践的な例

* 読み物です。

#### コンポーネント内でのアクションのディスパッチ

* store.js

``` js
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 51
  },
  getters: {
  },
  mutations: {
    increment: (state, n) => {
      state.count = state.count + n
    },
    decrement: state => state.count--,
  },
  actions: {
    increment: ({ commit } ) => {
      commit('increment', 10)
    }
  }
})
export default store

// store.dispatch('increment', {
//   amount: 10
// })
// console.log('store.state.count + 10 :',store.state.count)


// store.dispatch({
//   type: 'increment',
//   amount: 20
// })
// console.log('store.state.count + 20 :',store.state.count)
```

* App.vue

``` html

<template lang="pug">
  #app
    Counter

</template>

<script>
import Vue from 'vue'
import store from './store.js'
import { mapState } from 'vuex'
import { mapGetters } from 'vuex'
import { mapActions } from 'vuex'

const Counter = {
  template: `<div>
    <p> {{ count }}</p>
    <button @click="incrementMethods()">+10 buttton</button>
    <button @click="increment()">+10 buttton</button>
    <button @click="clickAction">+20 buttton</button>
    <button @click="add()">+10 buttton</button>
  </div>`,
  data: () => ({
    localCount: 999,
  }),
  methods: {
    incrementMethods() {
      return this.$store.dispatch('increment')
    },
    clickAction () {
      this.incrementBy({
        amount: 20
      })

      /* this.$store.dispatch('incrementBy', {
        amount: 20
      }) */
    },
    ...mapActions([
      'increment',
      'incrementBy',
    ]),
    ...mapActions({
      add: 'increment'
      })
  },
  computed: {
    storecount () {
    },
    ...mapGetters([
      ]),
    ...mapState({
      count: 'count',
    })
  }
}

export default {
  name: 'app',
  store,
  components: {
    Counter
  },
  data: () => ({
  }),
}
</script>


```

* コンポーネント内での、actionsのdispatchの使い方ですね。
* いろんなやり方がありますが、mapActions をうまく使いたいですね。

### アクションを構成する

* store.js

``` js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 51
  },
  getters: {
  },
  mutations: {
    someMutation: (state) => {
      state.count  +=1
    },
    increment: (state, n) => {
      state.count = state.count + n
    },
    decrement: state => state.count--,
  },
  actions: {
    actionA ({ commit }) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          commit('someMutation')
          resolve('success')
          reject('fail!')
        }, 1000)
      })
    },
    increment: ({ commit } ) => {
      commit('increment', 10)
    },
    incrementBy: ({ commit }, { amount } ) => {
      commit('increment', amount)
    }
  }
})
export default store

store.dispatch('actionA')
  .then((result) => { console.log(result)})
  .catch(result =>  console.log(result))

```

 * 非同期処理が終わったときの通知の仕方ですね。

 * store.js

```js

 const store = new Vuex.Store({
  state: {
    count: 51
  },
  getters: {
  },
  mutations: {
    someMutation: (state) => {
      state.count  +=1
    },
    someOtherMutation: (state) => {
      state.count +=2
    },
    increment: (state, n) => {
      state.count = state.count + n
    },
    decrement: state => state.count--,
  },
  actions: {
    actionB ({ dispatch, commit }) {
      return dispatch('actionA').then(() => {
        commit('someOtherMutation')
      })
    },
    actionA ({ commit }) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          commit('someMutation')
          resolve('success')
          reject('fail!')
        }, 1000)
      })
    },
    increment: ({ commit } ) => {
      commit('increment', 10)
    },
    incrementBy: ({ commit }, { amount } ) => {
      commit('increment', amount)
    }
  }
})
export default store

store.dispatch('actionB')
  .then((result) => { console.log(result)})
  .catch(result =>  console.log(result))
```
* actionBは、actionAが成功したら、someOtherMutation が実行されます。

* async は、勉強不足でうまく動かずです。
* また、更新がんばります。

* 今回は、これで終了です。