State
Single State Tree
単一の state 用 tree
Vuex は single state tree を用います。つまり、この単一のオブジェクトに、アプリケーションの全てのレベルの state を持たせ、そしてこのオブジェクトが "single source of truth" としての役割を与えます。(訳注: 大げさな言い回しだが、単にこのオブジェクトを参照すれば全てがわかりますよ、という状態にしておきますよ、ということ。) ですので、通常であれば各 App には、一つだけの store を用いるということです。single state tree になっていることによって、state の各部分がツリーのどの部分なのかということが容易にわかりますし、デバッグのために現在の App の状態のスナップショットを取るのも簡単です。
single state tree と、modularity (分割運用可能性) とは相反するものではありません。おって state と mutations を sub module へと分割していく手法についても説明します。
Getting Vuex State into Vue Components
Vuex の state を Vue Component に注入する
では store の中の state を Vue Component の中で表示するにはどうしたらいいでしょうか。Vuex の store は reactive なので、state を「読みだす」一番簡単な方法は computed property の中で store の state を return することです。
store.state.count が変更されるたびに、computed property が再評価されますので、結果としてこれが関連づけられている DOM が更新されます。
しかし上記のようなコードを書いてしまうと、グローバルにある store という変数を用いているので、モジュール化したコンポーネントの中で store を使おうとすると、全てのコンポーネントの中で store を import しなくてはいけなくなります。またコンポーネントのテストをする際にも、mock が必要になってしまいます。(訳注: const store = Vuex.store() と store を作ったファイルの中では store にアクセスできるが、別ファイルに切り出した component でこれを使おうと思ったら、store を import しなくてはいけない。これは現実的ではないし、面倒だ。ということ。)
そこで、Vuex は store を子 component に「注入(inject)」する機構を用意しています。ルートコンポーネントに store オプションを与えることでこれを実施できます。(ただし Vue.use(Vuex) を行っておいてください)
(訳注: store: store, としなくてもいいのは新しいシンタックス)
ルートインスタンスに store オプションを与えることで、子コンポーネント全てに store が注入されます。そして各コンポーネント内で this.$store という形でアクセスできるようになります。では、さっそく Counter が store をこの手法に使えるように書き換えてみましょう。
MapState ヘルパー
component が複数の store state を使う場合に、なんども computed properties の中で宣言するのは冗長です。そういう場合には mapState を用いてください。これによって getter function を作ることができます。
mapState に文字列の配列を渡すこともできます。ただし、mapped computed property の名前と state の sub tree の名前が同じ場合だけ、このように書くことができます。
Object Spread Operator
mapState は object を返します。では、他の local computed property とこの mapState で返されたオブジェクトを computed プロパティの中で組み合わせて使うには、どうしたらいいのでしょうか? 通常であれば複数のオブジェクトを一つにまとめる何かを使って、それでできたオブジェクトを computed プロパティに渡せばいいわけです。一番簡単なのは、object spread operator を使うことです。
Components Can Still Have Local State
local の state を持ってもよい
Vuex は全ての state を Vuex の中で管理するように、と強制しているわけではありません。もちろんより多くの state を Vuex で管理した方が、state の変更は明示的になりデバッグも簡単になります。とはいえ、時には煩雑で直感的でなくなってしまう場合もあります。もし state が単一のコンポーネントしか紐づいていないのであれば、それはローカルステイトとして切り離してしまった方がいいでしょう。常にこのトレードオフを判断し、アプリケーションに応じた手法を選択する必要があります。
Last updated