Vuexを使って大規模開発してみて思ったことやおすすめの設計
Vuejsで大規模なSPAの開発をしていて思ったこと。
コンテンツ
Vuexは必須
VuexとはVuejsで状態管理をするライブラリです。
名前からもわかるようにfluxやReduxから影響を受けていて、データの更新の流れを
actionでmutationを呼んでstateを更新するという一連の流れで制限します。
制限をかけることでデータの流れが一方向になるので流れが追いやすくなるというメリットがあります。
なぜ、Vuexが必要なのか?
Vuexを使うメリットはデータを持つ場所を1ヶ所にまとめることができること。
もし、Vuexを使わなかった場合は、データは各コンポーネント内で保有することになります。
アプリケーションで常時表示されるデータとしてよくあるのは自分のプロフィール名やアイコン画像。
このデータを設定ページから更新するとする。
Vuexを使わない場合は、各コンポーネント内のmethodsからAPIに更新リクエストを送る。
そして、返ってきたデータを表示されているコンポーネントに渡してあげなければならない。
Vuejsで同一階層にコンポーネントがある場合はあまり問題はないが、これが子や孫のコンポーネントとなると急に複雑になる。
Vuejsで子から親へデータを渡す場合はemitを使い、親から子に渡す場合はpropsを使う必要がある。
階層が深ければその分
コンポーネントA → コンポーネントB → コンポーネントC
とバケツリレーのようにデータを渡していかなければならず冗長だ。
小規模なアプリケーションであれば、この問題の深刻さには気づかないが大規模な開発をするとなるとこのバケツリレーのせいで思わぬバグに遭遇し、特定に時間がかかる。
大規模な開発においてVuexを選択した方が間違いなくいい。
Vuexを使うと上記の問題がすべて解決される。
Vuexの基本4つの要素
Vuexの中に含まれるactions、mutations、getters、stateこれらのことをStoreという。
State
stateはデータの状態だ。
各コンポーネントからここにアクセスすることができる。
コンポーネントで使うデータをstateに格納しておけば、コンポーネントがどの階層にあろうがstoreに直接アクセスするだけでデータを取得することができる。
よってバケツリレーをしなくて済む。
Getters
gettersはコンポーネント内でいうcomputedと同様の役割を担う。
stateに男女混合の住民データがあるとする。
ここから男性だけ、もしくは女性だけのデータを取得したい時などに使う。
別のstateに男性だけをフィルタリングしたデータを格納しておかなくても、getterにフィルタリングする処理を書いておけば、その結果を返してくれる。
また、住民データに更新がなかればキャッシュされたデータを返してくれるため高速に値を取得できる。
Mutations
Vuexでstateの値を更新したい場合、mutation内で更新する必要がある。
これは、前述したとおりデータの流れを追いやすくするためのテクニックである。
意図しない状態に変わるなどのバグに悩まされた時、状態の変更をしているのはmutation内だけなのでここを見るだけで解決することができる。
コンポーネントから呼ぶときはcommitでmutationにデータを送ることができる。
Actions
mutationは同期的でなければならないという制限がある。
APIにアクセスするなど非同期のコールバックを使う場合はactionsを使う。
actionsでデータが返ってきたときにmutationにcommitするのがルール。
これはやっておいた方がいいこと
名前空間は設定するのがおすすめ
SPAを作る時点である程度大きなアプリケーションになることは決まっているも同然。
当然同じ関数名を使いたくなるときがくる。
名前空間を設定しないと競合してしまう、実際僕が起きた問題はtagsというstateの競合。
実際tags以外にもよく使われる名称はいくつもある。
あらかじめ名前空間をつけておいた方がリファクタする手間が省ける。
computedは使わなくていい
コンポーネントのロールのデータを使わないといけないという状況を除いて基本的に算出関数はすべてgettersに書くのがいい。
computedに算出関数を書いてしまうとコンポーネントに依存してしまうので、Webページのレイアウトを変えたいときなど改修がめんどうになる。
getterに書いておけば、コンポーネントからそこにアクセスするだけなのでコンポーネントの切り分け時でも新たにそれに対応したコードを書く必要がない。
まとめ
と、こんな感じでVuexについて書いてみた。
詳しいことはVuexの公式ドキュメントに載っているので気になった方は見てみてください。