Vuex
What is Vuex
- State を予見可能な形で集中管理する
- 中規模・大規模なアプリに最適
- 小規模であればstore パターンで事足りるかも
はじめに
Vuex を使うのと、グローバルオブジェクトを使う場合との違い
- Vuex の store から取得した値はリアクティブになる
- Vuex の値は mutation を commit することによってのみ変更できる。これにより値の変更が追跡可能になる。
基本的な使い方
const store = new Vuex.Store({
state: {
count: 0,
},
mutations: {
increment(state) {
state.count++;
},
},
});
// mutationをコミットする
store.commit('increment');
// storeの値を取得する
console.log(store.state.count); // => 1
State
Single State Tree
Vuex の State は単一のオブジェクトで管理される。
コンポーネントで store を使う
// let's create a Counter component
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count() {
return store.state.count;
},
},
};
computed プロパティとすることで、store の更新を検知し、コンポーネントをアップデートできるようになる。
上記のやり方はスケールしないので、通常は下記のようにする。
// root Vue インスタンス
const app = new Vue({
// provide the store using the "store" option.
// this will inject the store instance to all child components.
store,
/* ... */
});
// コンポーネント
const Counter = {
computed: {
count() {
return this.$store.state.count;
},
},
};
mapState
react-redux の mapStateToProps と同じ機能。
this.$store.state
配下の各値をコンポーネントのcomputed
に手早くマップするときに使う。
import { mapState } from 'vuex';
export default {
computed: {
...mapState({
// ファンクションを使う方法
count: (state) => state.count,
// storeのキー名を使う方法
countAlias: 'count',
// ローカルStateと組み合わせる場合はノーマル関数を使う
countPlusLocalState(state) {
return state.count + this.localCount;
},
}),
},
// もしくは、キー名を配列で渡す方法もある
computed: {
...mapState([
// map this.count to store.state.count
'count',
]),
},
};
ローカルの computed と一緒に使う場合は下記のようにする。
computed: {
...mapState({})
localComputed () { /* ... */ },
}
Getters
- state の getter を設定することができる。computed の store 版と思えば OK。
- getter の再計算は、依存する値が変更された時のみ行われる(computed と一緒の挙動)
const store = new Vuex.Store({
state: {
count: 1,
},
getters: {
bigCount: (state) => state.count * 10,
// 第2引数に他のgetterを取ることもできる
moreBigCount: (state, getters) => getters.bigCount * 10,
},
});
Getter へのアクセス
コンポーネントからはthis.$store.getters
で取得できる。
computed: {
bigCount () {
return this.$store.getters.bigCount
}
}