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
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
<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
<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を呼び出すだけになり、スマートになる事と、バグが減らせるわけですね。
ゲッターに引数を渡す
- src/store.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
<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
<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
<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
<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>
- ゲッター編は、これで終了です。