📝

フロントエンドの設計

2024/02/25に公開

最近仕事でフロントをやっていて、まわりではほぼ設計もせず、画面仕様が決まればいきなりそれ通りに実装がされている状況でした。(請負ではなく自社サービスのため納品とかの必要がない)
それでもきちんと作っているならまだしも、結果は責務の分離ができていないコンポーネントや色々な箇所から好き勝手触られるStoreなど、うかつに変更すればバグを踏み抜くことが多々ある悲惨な状況です。
そこで自分の中でこれくらいはなんとなくでも方針決めてやればいいのにと思うことを書き綴っておきます。

前提として以下フレームワークを使用しています。
Vue3、Pinia

パーツ構成を考える

画面のパーツを作成する際、どの程度分割するかや、どのパーツ(コンポーネント)がどこまでの役割をもつかを決めます。

例えば、検索用の入力フォームとその結果を表示する画面を作成するとしたとき、以下のような構成が考えられます。

場合データとして検索内容と検索結果があり、それぞれSearchInputFormとSearchResultがマスターデータを保持することになるかと思います。
そのため、各データの操作などは子の画面で好き勝手に行わず、データを管理している親コンポーネント側で行う想定です。
子の画面は常に親からデータを受け取り、更新を親に通知してもらうような感じです。

実際はComposableな関数に切り出すなど処理の分割や、データの受け渡しも親からひ孫などの場合に単にバケツリレー以外の方法を取ることはあるかと思います。

Storeの扱い

個人的に思っているのは以下のようなケースで使い、誰が参照するかを明確にしておく必要があると考えています。

  • 全画面共通的に使用する情報(設定やログインユーザーの情報など)
  • 親子関係のないコンポーネント間でデータを共有したい場合
  • SPAで別画面に移動したあともデータを保持しておく必要がある場合

いずれの場合も使用する場合は機能ごとに一つではなく、管理したいデータと関連するデータごとに一つのつもりとしたほうがよいと思っています。

そうして適切な名前をつけて管理する情報を決めておかないと、以下のような状況に陥り誰が何を必要としているのかがわからなくなりがちです。

  1. 対象機能で必要な複数の処理用のデータを一つのStoreに詰め込まれる
  2. 処理ごとに別のコンポーネントに別れているため、色々なコンポーネントから一つのStoreが参照、データの更新が行われる
  3. 結果色々な箇所から参照更新が行われているため、一部変更しようとしたとき想定外の箇所で不具合が起こる

ということで、Storeを使う場合は

  • 管理するデータを決める
  • 全画面で使用するものと一部で使用するものは分けて管理する
  • Storeにアクセスするコンポーネントは可能な限り親側のコンポーネントとし、その子に対しては親がデータの受け渡しと更新を行う

あたりを意識した設計ができているとよいと思います。

補足
Vue3ではPinuaなどのStoreを使用しなくとも、一部の画面内での状態をProvide/Injectでやりとりする方法もあるかと思います。

まとめ

とういうことで色々思ってることを雑多に書きまとめました。
実際は使用するフレームワークや構成によりこの限りではない、他の手段も取れるかとは思います。
ただ登場人物がどれだけいて、誰がどういった責務をもつか、実質グローバル変数のようなStoreを複雑にしないためにどこでどう使用するかを決めるなど、フロントだからどうこうという部分以前のところをしっかりとおさえるべきなのかと思っています。

Discussion