Vue.jsの概要はふんわり理解している前提です。
概念図
Vuexの役割
ストアの状態を管理する。
コアコンセプト(State, Getters, Mutations, Actions, Modules)ごとに定義する。
ストアって何
コンポーネントをまたいで共通に使用するデータ。
Vuexのストアはリアクティブに扱える。
Vuexを使うコンポーネントの役割
Vuexで状態管理されているデータを参照したり、状態を変更するイベントの発火を定義する。
コンポーネントから直接状態を変更したり処理したりはできない。
(一応機能としてはできるけど設計的に好ましくはないから極力使わない。)
コアコンセプトのざっくりとした役割
コアコンセプト | 役割 |
---|---|
State | Vuexで状態管理するデータの定義 |
Getters | State用の算出プロパティ |
Mutations | Stateの状態変更の定義 |
Actions | Mutationsを発火させるイベントの定義 |
Modules | 役割やモジュールごとに分割して定義する機能 |
コアコンセプトのもう少し詳しい役割
State
Vuexで状態管理するデータの定義。
一つのコンポーネント内で完結するデータであればわざわざVuexを使う必要はない。
例えばショッピングサイトのカートの中身とか。
Getters
Stateの状態によって毎回計算させるようなデータがある時に役立つ。
コンポーネント内でいうところの算出プロパティみたいなもの。
例えばToDoリストの未完了項目を取得するとか。
Mutations
Stateの状態変更の定義。
Stateの状態変更はmutationsで定義されたものでしかできない。
例えばToDoリストに追加や削除がある場合とか。
Actions
Mutationsを発火させるイベント処理の定義。
コンポーネントからStateの状態を変更するときはここから発火させる。
コンポーネント内でいうところのmethodsに近い。
StateにかかわりのあるイベントはmethodsではなくActionsに定義する。
一つのコンポーネント内で完結するイベントの場合はStateに定義されたデータを使ってないはず。
Modules
Storeは基本的に「./store/index.js」で定義する。
State、Mutationsなどをそれぞれ別ファイルに分割して管理することができる。
「state.js」「mutations.js」などを「index.js」に読み込ませて使う。
また、State~Actionsまでをセットにして、機能ごとに分割することもできる。
「./store/moduleA/index.js」「./store/moduleA/index.js」などを「./store/index.js」に読み込ませて使う。
それぞれの機能ごとに名前空間を独立させたりもできる。
補足
Vuexを使わなくても状態管理って実現できるのでは?
できるけどpropsの定義を常に気にしなきゃいけなかったり、管理が複雑になりやすい。
ごく小規模ならVuexを使わない方が管理しやすいかもしれない。
Vuexを使わずにストアパターンを自分で実装するのも一つの手。
コンポーネントからMutationsを発火させればActionsいらないのでは?
Actionsに定義した方が構成がわかりやすいだけで、使わないと動作しないとかではない。
Mutationsでイベント処理も一緒にやってもいいけど、分けた方がわかりやすい。
シンプルな機能の場合、わざわざActionsに定義すると冗長になる場合もあるから、公式ガイドでも使用を許可してる。
ただし、非同期処理はMutationsでは使えないからActionsを使う。