Posted at

Vuexのドキュメントを呼んでみたので書き連ねてみる

Vuexについてのドキュメントを読んでみたので、備忘録としてまとめてみます。

https://vuex.vuejs.org/ja/guide/


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のコミット