Vuexについてのドキュメントを読んでみたので、備忘録としてまとめてみます。
Vuex入門
Vuexの中心となりのはstore
storeは基本的にアプリケーションの状態を保持するコンテナ
Vuexストアはリアクティブ
ストアの状態は直接変更することが出来ない
ミューテーションをコミットすることによってのみ状態を変更することかできる
ステート
Vuexは単一ステートツリーを使用する
アプリケーションレベルの全ての状態が含まれており、
信頼出来る唯一の情報源である
状態の特定の部分を見つけること
デバッグのために現在の状態よスナップショットを撮ることを容易にする
とはいえ、モジュール性がサポートされており、storeをモジュール化する機能も備えている
componentからstoreの値を使いたいときにthis.$store.state.hogeをcomputedプロパティで書くのが一般的だが、冗長なため、mapStateを使うことで、簡略化できる
mapSateの中では、this.storeは省略でき、引数にstoreを取るメソッドをプロパティに持つオブジェクトを書く
ステートの名前が同じであれば文字列配列の形で書くと勝手にマッピングしてくれる
mapStateはオブジェクトを返すので、
他のローカルプロバティと共存させるときにmapStateの中身を展開させる必要がある
そのときにes6のスプレッド演算子は便利
getter
ゲッターは引数に関数をとり、その関数の引数はstate
第2引数にはgettersのゲッター一覧が取得できる
コンポーネントからはthis.$store.gettersでアクセスできる
基本的にはゲッターはキャッシュされ、再計算されない
メソッドスタイルでの定義もでき、stateを引数にとるメソッドのなかで、関数を新たに定義する
Idでリストの中のデータを取得するときに便利
メソッドスタイルはvueのリアクティブシステムにおいてキャッシュされないので毎回計算が走る
Mapstateと同様にmapGettersも使える
Mutation
ストアの状態を変更出来る唯一の方法
イベントハンドラ的存在
Mutationは別ファイルにtypeだけを記述する
使う時はimport
Payloadはオブジェクトで渡すと良い
1つのオブジェクトでtypeとペイロードをまとめることもできる
子コンポーネント内でミューテーションをコミットする際はthis.$store.commitかmapMutationsを使う
mapMutationsはthis.store.commitへマッピングするもの。スプレッド演算子を使う
全てのミューテーションは同期的
非同期と状態変更は分離したい、いつ変更されたかわからなくなる
Action
アクションは状態を変更するのではなく、ミューテーションをコミットする
アクションは非同期処理を行うことが出来る
引数分割束縛は、プロパティ名を関数定義の時点で固定し、実際にはオブジェクトが渡された時もそのオブジェクトのプロパティを束縛できる
commit、state,getterはコンテキストから呼びだすことができる
Dispatchを使ってアクションは呼び出せる
dispatchもcommitと同様にペイロードを送れる
外から成功時と失敗時のコールバック渡すといい感じにそれぞれmutationをコミットできる
Actionでの非同期処理はPromiseを返すといい感じ
Actionの中で別のactionをdispatchできる
Async awaitを使う時さらにいい感じに
Action定義時にasync付けれる
Module
ストアを複数にわけることができる
モジュールは、オブジェクトの形
モジュールの中で取得するstateほローカルState
1番ルートのStateはrootStateでアクセスできる
モジュールの中でnamespaceをtrueにするとそのモジュールの中のactionsやmutationsを呼ぶ時にprefixを付けてくれる
namespaceは親モジュールから継承されるためモジュールにprefixを付けることなくモジュールアセットを使用することが出来る
モジュール内でgetterを使う場合親のgetterを呼び出す場合、
第4引数にrootgetterを受け取ることかできる
モジュール内で親actionまたはmutationにdispatchまたはcommitする場合、第3引数にroot:trueを設定する
アプリケーションの構造化
アプリケーションの構造としては、以下が満たせていればOK
1アプリケーションレベルの状態はストアに集約される
2状態を変更する唯一の方法は同期的に行うミューテーションをコミットすること
3非同期的なロジックはカプセル化されるべきであり、アクションによって構成される
ファイルが大きくなりすぎた場合は、ゲッター、ミューテーション、アクションごとに別ファイルに切り出せる
Plugin
状態のスナップショットを撮る時などに便利。
ミューテーションの前後でイベントをハンドリングできるので変更前と変更後での比較ができる
ストアの状態のディープコピーをするために
_.cloneDeep関数を呼ぶ
スナップショットを取るのは開発用だけである必要があるため、webpackのdefinePluginを使う
createLoggerでログ出力できる
厳格モード
VuexStoreの定義時にstrict:trueにすればおけ
ミューテーションハンドラの状態が外部から変更された時にエラーがなげられる
本番環境では厳格モードはしようしてはならない
ステートツリーに対して深い監視を実行するためパフォーマンスに影響が出るため
フォームの扱い
厳格モードでv-modelを使用する時
ユーザーがインプットしたとき算出プロパティは更新しようとするがこの更新はミューテーションハンドラ内部で行われていないので、エラーが投げられる
対応策1
computedからストアのデータを取得。inputイベント時にmutationをコミットするようにすると厳格モードでも使用できる
対応策2
v-modelを使う方法もある
算出プロパティのゲッターとセッターを使う
Getterでstateの変更
Setterでmutationのコミット