Vuex コアコンセプト ステート編
今回のお題は、こちらです。
https://vuex.vuejs.org/ja/core-concepts.html
構成
.
├── README.md
├── index.html
├── package-lock.jsona
├── package.json
├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── main.js
│ └── store.js
└── webpack.config.js
ステート
Vuex の状態を Vue コンポーネントに入れる
- App.vue
<template lang="pug">
#app
Counter
</template>
<script>
import Vue from 'vue'
import store from './store.js'
const Counter = {
name: 'Counter',
template: `<div>{{ count }}</div>`,
computed: {
//- アロー関数
count: () => store.state.count
}
}
Vue.component('Counter', Counter)
export default {
name: 'app',
data () {
return {
privateState: {},
}
},
computed: {
count () {
return store.state.count
}
},
methods: {
increment() {
return store.commit('increment')
},
decrement() {
return store.commit('decrement')
}
}
}
</script>
- src/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 51
},
mutations: {
increment: (state) => {
state.count++
},
decrement: state => state.count--,
}
})
export default store
- es6 の省略記法は、見比べていたら慣れてくるので、使うようにします。
- storeのstateをコンポーネントのcomputedを使って、表示させているだけです。
ルートインスタンスに store オプションを渡す
- App.vue
<template lang="pug">
#app
Counter
button(@click="increment") +
button(@click="decrement") -
</template>
<script>
import Vue from 'vue'
import store from './store.js'
const Counter = {
name: 'Counter',
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
Vue.component('Counter', Counter)
export default {
name: 'app',
//
// store option
//
store,
data () {
return {
privateState: {},
}
},
computed: {
count () {
return this.$store.state.count
}
},
methods: {
increment() {
return this.$store.commit('increment')
},
decrement() {
return this.$store.commit('decrement')
}
}
}
</script>
- ルートで storeを指定することで、別ファイルのコンポーネントであろうが、すべて this.$store で storeにアクセスできるみたいです。
- thisを使っている箇所は、参照先が異なるので、アロー関数から変更しています。
コンポーネントを別ファイルにしてみる。
- 別ファイルにして、storeをimport にしなくても問題ないことを確認します。
- 構成
.
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── src
│ ├── App.vue
│ * ├── Counter.vue
│ ├── assets
│ │ └── logo.png
│ ├── main.js
│ └── store.js
└── webpack.config.js
- src/Counter.vue
<template lang="pug">
div {{ count }}
</template>
<script>
export default {
name: 'Counter',
computed: {
count () {
return this.$store.state.count
}
}
}
</script>
<style lang="scss" scoped>
</style>
- App.vue
<template lang="pug">
#app
Counter
button(@click="increment") +
button(@click="decrement") -
</template>
<script>
import Vue from 'vue'
import store from './store.js'
import Counter from './Counter'
Vue.component('Counter', Counter)
export default {
name: 'app',
store,
data () {
return {
privateState: {},
}
},
computed: {
// count () {
// return this.$store.state.count
// }
},
methods: {
increment() {
return this.$store.commit('increment')
},
decrement() {
return this.$store.commit('decrement')
}
}
}
</script>
- 表示部分を別ファイルにしましたが、特に問題なく表示されていますね。
mapState ヘルパー
- Counter.vue
<template lang="pug">
div
div {{ count1 }}
div {{ count2 }}
div {{ count3 }}
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'Counter',
data: () => ({
localCount: 999
}),
computed: mapState({
count1: state => state.count,
count2: 'count',
count3 (state) {
return state.count + this.localCount
}
})
}
</script>
<style lang="scss" scoped>
</style>
- App.vue
<template lang="pug">
#app
Counter
button(@click="increment") +
button(@click="decrement") -
</template>
<script>
import Vue from 'vue'
import store from './store.js'
import Counter from './Counter'
Vue.component('Counter', Counter)
export default {
name: 'app',
store,
data () {
return {
privateState: {},
}
},
computed: {
},
methods: {
increment() {
return this.$store.commit('increment')
},
decrement() {
return this.$store.commit('decrement')
}
}
}
</script>
- mapStateヘルパーを使うことで、computedでの関数を纒めて、作れるみたいですね。
- count1 は、アロー省略記法です。
- count2 は vuexの省略記法みたいです。
- count3 は、thisの関係で通常の関数です。
- this.$storeで書くより楽ですね。
配列で渡す
- Counter.vue
<template lang="pug">
div
div {{ count }}
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'Counter',
data: () => ({
localCount: 999
}),
computed: mapState([
'count'
])
// computed: mapState({
// count1: state => state.count,
// count2: 'count',
// count3 (state) {
// return state.count + this.localCount
// }
// })
}
</script>
<style lang="scss" scoped>
</style>
- 名前を変えないのであれば配列で渡すとさらに、省略できますね。
オブジェクトスプレッド演算子
- App.vue
<template lang="pug">
div
div {{ count }}
div {{ localCount }}
div {{ localComputed }}
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'Counter',
data: () => ({
localCount: 999
}),
computed: {
localComputed () {
return this.localCount + 1
},
...mapState([
'count'
])
}
}
</script>
<style lang="scss" scoped>
</style>
スプレッド演算子は、スマートにローカル側とstore側を連結できます。
ステート編は、これで終了です。