ボタンコンポーネントを設計してみる
2019年9月24日
皆さんこんにちは末ちゃんです。
雲が高くなり、秋空になってきたという話を社内でしたら誰も理解してくれませんでした。皆さん、季節毎の空の違いとかってあまり気にしないものなんでしょうか・・・。
ボタンコンポーネントを設計してみる
さて、今回のテーマですがボタンのコンポーネントを設計してみようかなと思います。
今回はVue.jsの書き方でやっていきます。
たかがボタンコンポーネント、されどボタンコンポーネントです。
普段何気なくコーディングしているものを紐解いてみると、実はかなり時間をかけて書いているものだったと気付かされます。
最低限のマークアップ
まずは最低限のマークアップをしていきましょう。
<button>ボタン</button>
言ってしまえばボタンなんてこれだけのことですね。
発生しうるデザインパターン(Modifier)を想定する
このボタンに発生しうるデザインパターンを想定していきます。
- base
- border
- fill
カラー
色もパターンが発生してきますね。
- brand
- success
- negative
- action
状態
ボタンの状態を示すものも必要ですね。
- disabled
- loading
- checked
ざっとこんなところにしておきましょうか。
もちろんプロジェクトに応じてこれ以上のパターンが存在してくるでしょう。
更に言えば、アイコン付きや、サイズ違いのパターンなども実際には必要になってくることと思います。
コードに起こしてみる
ここまでをコードに起こしてみるとこんな感じでしょうか。
<template> <button class="btn" :class="extendCss" :disabled="status === 'disabled'" > <span v-if="status === 'loading'" class="loading"></span> <span v-else-if="status === 'checked'" class="checked"></span> <span v-else>{{ label }}</span> </button> </template> <script> export default { props: { label: { type: String, default: 'ボタン' }, type: String, color: Array, status: String }, computed: { extendCss: function() { let css = '' if (this.type) css = `${css} btn--${this.type}` if (this.color.length) { this.color.forEach((x) => { css = `${css} btn--${x}` }) } if (this.status) css = `${css} btn--${this.status}` return css } } } </script> <style> <!-- 各modifierを含めたスタイル --> </style>
※ 実際に動作確認しているわけではありません。
こんなコードになってくるのかなと思います。
これで36パターンのボタンが1つのソースで管理できることになります。
もちろんこれだけでは恐らくほとんどのプロジェクトで不足するでしょう。先述したようにアイコンをつけるシチュエーションもあるでしょうし、ここでは <button>
でマークアップしましたが、<a>
でマークアップしたい場合もでてくるでしょう。
こういったコンポーネントを作らずにコーディングしていく場合、これだけのパターン以上のものを手書きで管理していることになります。改めて恐ろしく感じますね。
このようにコンポーネントで管理していれば、ソースや書き方がぶれるのを防ぐ事ができます。
まとめ
一度このようにコンポーネントを作っていくのには多大な時間がかかります。デザインから発生するパターンをリスト化し、テスト用データをセットしながらコードに起こしていく訳ですから。
しかし、一度組み上げてしまえば変更が非常に容易かつ安全に行うことができます。
さぁ、フロントエンドライフを楽しみましょう。