レイヤーである。ロジックをDOMから分離することによってテストがしやすくなる
Usage
- ルートコンポーネントに
store
オプションを設定する
子コンポーネントでthis.$store
を利用することができるようになる
子コンポーネントには自動で設定される
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
let store = new Vuex.Store({});
let app = new Vue({
store,
}).$mount('#app');
state
stateはコンポーネントのcomputed内で下記の形式で利用することができる。
computed: {
foo() {
return this.$store.state.foo
}
}
mapStateを使用すると以下のようにthis.$store
を省略することができる
computed: {
...mapState({
// this.foo()
foo: state => state.foo,
foo_1(state) {
return state.foo + 1;
}
})
}
Getter
getterはstateの値を取得するための関数
let store = new Vuex.Store({
state: {
items: [
{id: 1, name: "foo"},
{id: 2, name: "bar"},
]
},
getters: {
// moduleではstate,getters,rootState,rootGettersを使用する
foo : (state, getters) => {
return state.items.filter(item => item.name == 'foo')[0]
},
// 関数を返すgetterを定義することで引数を渡すことができる
getItemById: (state, getters) => (id) => {
return state.items.filter(item => item.id == id)[0]
}
}
});
store.getters.foo
// {id: 1, name: "foo"}
store.getters.getItemById(2)
// {id: 1, name: "foo"}
mapGetters
はコンポーネント内のcomputedでthis.$state.getters
を省略することができる
computed: {
...mapGetters({
// store.getters.foo => this.foo
foo: 'foo',
// store.getters.getItemById(2) => this.getItemById(2)
getItemById: 'getItemById'
})
}
Mutation
-
state
を変更する処理を記述する。その処理は同期処理でなければならない。 非同期処理はActionに記述する。 -
store.commit(ミューテーション名, payload)
で指定したミューテーションを呼び出す。 -
リアクティブ性を保持するためにオブジェクトの属性を変更する際は下記のようにする
Vue.set(state.foo, 'foo', 1);
state.foo = { ...state.foo, bar: 1 };
state: {
foo: 1
},
mutations: {
increment (state, payload) {
state.foo += payload.foo;
}
}
- mapMutationsを使用することでコンポーネントのmethodで省略して書くことができる
methods: {
...mapMutations({
// this.$store.commit('foo', 1)をthis.foo(1)で利用することが可能になる。
foo: 'foo',
})
}
Action
-
action
はmutation
をcommit
する -
action
は非同期的な処理を行うことができる -
action
はstore.dispatch(アクション名, payload)
で実行する -
actionはPromiseを返すことによって
this.$store.dispatch('actionName').then(() => {...})
のような書き方ができる -
{ state, rootState, commit, dispatch, getters, rootGetters }は
aciton
の第1引数
actions: {
foo ({ state, rootState, commit, dispatch, getters, rootGetters }, payload) {
commit('foo', payload)
}
}
methods: {
...mapActions({
// this.$store.dispatch('foo', payload) => this.foo(payload)
foo: 'foo'
})
}
Module
-
state
は関数にする -
デフォルトでは
state
以外はglobalに置かれる namespaced: trueにすればすべてlocalに置かれる -
getterの引数
state, getters, rootState, rootGetters
-
actionの第1引数
{dispatch, commit, getters, state, rootGetters, rootState}
-
localからglobalに値をコミットする場合はcommitとdispatchの第3引数に
{root: true}
をセットする
Vuex.Store *
-
Storeはアプリケーションで1つ
-
storeに新しい属性を付与する時はリアクティブ性を持たせるためにVue.set()もしくは新しい値をセットする
-
store.stateにデータを保存する
-
mapStateはthis.$storeを省略することができる
-
computedの中で
...mapState
する -
store.gettersはstateに関連するデータを取得する関数を登録する *
-
mapGettersはcomputedにstore.gettersのキーをマッピングする際に利用する
-
stateはmutationsにあるメソッドを通じて変更する this.$store.commit(mutationsのキー, 値)
-
mutationsないでは同期処理を行う
-
actionsはmutationsのコミットを行う
this.$store.commit(mutationsのキー, 値)
非同期的な処理を実行してもよい
actionsの実行はstore.dispatch(アクション名, param)
コンポーネント内ではthis.$store.dispatch(アクション名, param)
actions内部はPromiseで囲む
例外はcatch()で取得 -
modulesはstoreの設定を分割して定義することができる
states以外はデフォルトではglobalにおかれる
states以外もnamespaceをおきたい場合はnamespaced: true
名前空間を使用した場合以下のような形式にする
this.$store.getters[‘foo/bar’]
this.$store.getters[‘モジュール名/キー名’]
this.$store.dispatch(‘モジュール名/キー名’, payload);
store.registerModule()とstore.unregisterModule()で動的にモジュールを登録することができる。
モジュールではstateはローカルステートとルートステートに分かれる -
routerをvuexで利用したい場合はvuex-router-syncを利用する