フロントエンドに関わっているエンジニアであればAtomic Designというのを聞いたことがあるかもしれません。
フロントエンドの開発をしていく上で大事なことの一つに、画面の部品をどのようにComponentに分割していくかというものがあります。
きっとたくさんのフロントエンドエンジニアがこの点については毎回悩まれると思います。
そこで、どのように分割していくと良いかという指標の一つとしてAtomic Designという考え方があると僕は解釈しています。
Atomic DesignはBrad Frostさんという方が提唱したもので、英語であれば下記にて公開されていますし、本を注文することもできます。
また、日本では下の書籍がReactを使って具体的にわかりやすく説明されています。(ただし、SPAフレームワークを触ったことが無いとちょっとつらいかも)
Atomic Design ~堅牢で使いやすいUIを効率良く設計する
- 作者: 五藤佑典
- 出版社/メーカー: 技術評論社
- 発売日: 2018/04/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
この記事ではAtomic Designについては詳しく見ないので、そもそもAtomic Designについて知りたい方は上の書籍や、わかりやすいブログ記事も多数あるのでそれらを先に読むことをおすすめします!
ではこの記事で何を述べるかと言うと、Vue.jsのVuexを使ったプロジェクトでAtomic Designを採用した場合に、VuexのStoreとAtomic DesignのComponentがどのようにやり取りすると良いかを紹介します。
あくまでこのやり方は1例に過ぎず、やり方は多数ありますので迷っている方の参考になればと思います!(CYDASでもやり方は日々アップデートしています!)
Atomic DesignとVuexで何に迷うのか
これは「Atomic Designだから」、という問題では無いのですが「誰がVuexを意識するのか?」という課題が常につきまとってきます。
具体的には:
- 誰がVuex StoreからStateを受け取ることができるのか
- 誰がVuex StoreにActionを
dispatch
していいのか
という2点がポイントになってきます。ここに一定のルールを設けないと、そこら中からStateを受け取ったり、そこら中からActionをdispatch
したりしてどこで何が起きているのかかなり追いづらくなってしまいます。
イメージとしては下図のような状況です。
「Pages, Templates, OrganismsはPropsを受け取ることもあれば、Storeからstate
を受け取ることもあり、eventを$emit
することもあればStoreにdispatch
することもある。」のがわかります。
これでは流れが追いにくかったり、実装するときも迷いが生じやすくなります。
Atomic DesignとVuexの良い関係
そこで、僕が今のところ良いと思っているAtomic DesignとVuexの関係は下図のようになります。
言語化すると、
- Storeからstateを受け取るのはPagesのみ
- Pages以外はPropsでしか入力を受け付けない
- Storeに
dispatch
して良いのはPagesとTemplatesのみ - Pages, Templates以外は
dispatch
してはいけない(イベントは$emit
するのみ)
というルールになります。
StoreはPagesのみが意識すべきでは?
ここで出てきそうなのが「StoreはPagesのみが意識すべき」という意見です。
ルールとしてはわかりやすいんですけど、実際にやってみるとTemplates→Pagesにeventを$emit
して、PagesからStoreにdispatch
するのが冗長に思いました。
Templates→Pagesへの$emit
が増えるほどPagesでもイベントハンドラが増えてしまうのです。。。(やり方はいくつかあるにせよ冗長さは避けられないと思います)
そういうわけでCYDASでは「dispatch
に関してはTemplatesからやってもいいのでは?」という意見もあってTemplatesまではStoreを意識して良いルールにしています。
Pagesはいつdispatch
する?
Templatesがdispatch
するなら、むしろPagesはいつdispatch
するのか?という疑問も出てくると思います。
基本的にOrganismsより下の層から$emit
されたイベントについてはTemplatesからStoreにdispatch
します。
なので、Pagesがdispatch
するタイミングはmounted
などの、ページ初期化時などのタイミングくらいしか無いのかなと思っています。
TemplatesにPropsは必要なのか?
Templatesからdispatch
ができるなら、いっそのことstate
もStoreから持ってこればいいのでは?という疑問も出てきます。
それをやってしまうともはやPagesが必要なくなると思うのですが、あくまでデータはProps経由でもらうというルールにしています。
というのも、Atomic Design(にこれも限らずですが)とStorybookを組み合わせて使うことも多いかと思います。
このStorybook上でTemplatesを表現する際に、Propsで制御できたほうがVuexのセットアップ(getters
だったりstate
だったり)が必要なくなります。
標準のVue.jsで、Propsにデータを差し込むだけでいろいろなデータを流し込めるので、変に手間のかかることをせずに済むと思っています。
そういったわけで、TemplatesはPropsでデータを受け取るようにしています。
まとめ
この記事で述べているやり方はあくまで1例にすぎません!大事なのは皆が好き勝手違う書き方をしてしまわないようにルール(コーディング規約)をある程度決めておくことだと思います。
そしてやってみて、フィットしなかったらもっと良いと思う方法に変えていけば良いんだと思います(手戻りは発生してしまうのは覚悟の上で)!
参考