初心者がVuexの公式ガイドを勉強するメモ コアコンセプト　ゲッター編

# Vuex コアコンセプト  ゲッター編
## 今回のお題は、こちらです。
### https://vuex.vuejs.org/ja/core-concepts.html

## ゲッター
### 構成


```
.
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── src
│   ├── App.vue
│   ├── Counter.vue
│ * ├── Todo.vue
│   ├── assets
│   │   └── logo.png
│   ├── main.js
│   └── store.js
└── webpack.config.js
```

* src/store.js

``` js

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

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'text1', done: true },
      { id: 2, text: 'text2', done: false },
      { id: 3, text: 'text3', done: true },
    ],
    count: 51
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    },
    doneTodosCount: (state, getters) => {
      return getters.doneTodos.length
    }
  },
  mutations: {
    increment: (state) => {
      state.count++
    },
    decrement: state => state.count--
  }
})
export default store

```

* App.vue

``` html
<template lang="pug">
  #app
    todo
    //- Counter
    //- button(@click="increment") +
    //- button(@click="decrement") -
</template>

<script>
import Vue from 'vue'
import store from './store.js'
import Counter from './Counter'
import Todo from './Todo'

Vue.component('Counter', Counter)
Vue.component('todo', Todo)

export default {
  name: 'app',
  store,
  data () {
    return {
      privateState: {},
    }
  },
  computed: {
  },
  methods: {
    increment() {
      return this.$store.commit('increment')
    },
    decrement() {
      return this.$store.commit('decrement')
    }
  }
}
</script>

```

* Todo.vue

```html
<template lang="pug">
  div
    ul(v-for="todo in doneTodosList")
      li {{ todo }}
    p 完了数: {{ doneTodosCount }}

</template>

<script>
export default {
  name: 'Todo',
  data: () => ({}),
  computed: {
    doneTodosCount () {
      return this.$store.getters.doneTodosCount
    },
    doneTodosList () {
      return this.$store.getters.doneTodos
    }
  }
}
</script>

<style lang="css">
</style>
```


* 個々のcomputedに、getter関数を書くのではなく、storeに共用のgetter関数を書く事で、各computedは、getterを呼び出すだけになり、スマートになる事と、バグが減らせるわけですね。

![getter_thid.png](https://qiita-image-store.s3.amazonaws.com/0/131175/71d04ecf-a82d-fe3a-a0ad-db418ac8412a.png)


#### ゲッターに引数を渡す

* src/store.js

``` js

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

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'apple', done: true },
      { id: 2, text: 'banana', done: false },
      { id: 3, text: 'Natto', done: true },
    ],
    count: 51
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    },
    doneTodosCount: (state, getters) => {
      return getters.doneTodos.length
    },
    getTodoById: (state) => (id) => {
      return state.todos.find(todo => todo.id === id)
    }
  },
  mutations: {
    increment: (state) => {
      state.count++
    },
    decrement: state => state.count--
  }
})
export default store
```

* App.vue

```html
<template lang="pug">
  #app
    todo
    //- Counter
    //- button(@click="increment") +
    //- button(@click="decrement") -
</template>

<script>
import Vue from 'vue'
import store from './store.js'
import Counter from './Counter'
import Todo from './Todo'

Vue.component('Counter', Counter)
Vue.component('todo', Todo)

export default {
  name: 'app',
  store,
  data () {
    return {
      privateState: {},
    }
  },
  computed: {
  },
  methods: {
    increment() {
      return this.$store.commit('increment')
    },
    decrement() {
      return this.$store.commit('decrement')
    }
  }
}
</script>

```

* Todo.vue

```html
<template lang="pug">
  div
    p ID検索
    p {{ idSearch(id) }}

    input(v-model.number="id" placeholder="2")
    p 完了リスト
    ul(v-for="todo in doneTodosList")
      li {{ todo }}

    p 完了数: {{ doneTodosCount }}
    p {{ id }}

</template>

<script>
export default {
  name: 'Todo',
  data: () => ({
      id: ''
    }),
  methods: {
    idSearch (id) {
      return this.$store.getters.getTodoById(id)
    }
  },
  computed: {
    doneTodosCount () {
      return this.$store.getters.doneTodosCount
    },
    doneTodosList () {
      return this.$store.getters.doneTodos
    },
  }
}
</script>

<style lang="css">
</style>
```

* IDなど、特定の引数を渡すことができますね。
* 引数を渡す必要があるため、computedでは無く、methods で処理しています。



#### mapGetters ヘルパー

* src/Todo.vue

```html

<template lang="pug">
  div
    p ID検索
    p {{ idSearch(id) }}

    input(v-model.number="id" placeholder="2")
    p 完了リスト
    ul(v-for="todo in doneTodos")
      li {{ todo }}

    p 完了数: {{ doneTodosCount }}
    p {{ id }}

</template>

<script>
import { mapGetters } from 'vuex'

export default {
  name: 'Todo',
  data: () => ({
      id: ''
    }),
  methods: {
    idSearch (id) {
      return this.$store.getters.getTodoById(id)
    }
  },
  computed: {
    ...mapGetters([
      'doneTodosCount',
      'doneTodos'
    ])
  }
}
</script>

<style lang="css">
</style>
```

* mapGetters配列を使うと随分すっきりしますね。

#### 名前を変える場合は、オブジェクト形式に変更します

* Todo.vue

```html

<template lang="pug">
  div
    p ID検索
    p {{ idSearch(id) }}

    input(v-model.number="id" placeholder="2")
    p 完了リスト
    ul(v-for="todo in doneTD")
      li {{ todo }}

    p 完了数: {{ doneCount }}
    p {{ id }}

</template>

<script>
import { mapGetters } from 'vuex'

export default {
  name: 'Todo',
  data: () => ({
      id: ''
    }),
  methods: {
    idSearch (id) {
      return this.$store.getters.getTodoById(id)
    }
  },
  computed: {
    ...mapGetters({
      doneCount: 'doneTodosCount',
      doneTD: 'doneTodos'
    })
    //-...mapGetters([
      //-'doneTodosCount',
      //-'doneTodos'
    //-])
  }
}
</script>

<style lang="css">
</style>
```

* ゲッター編は、これで終了です。