Vueのコンポーネントパターン


この記事は ユニークビジョン株式会社 Advent Calendar 2021 11日目の記事です。

今回は社内でよく使われるVueコンポーネントを切り分けるパターンについて説明します。

最終的には一つの責務にまとまるようにコンポーネントを分けます。
以下に上げるのはその責務の分ける一種の基準になると考えてください。

コンポーネントをどう分けるか判断に迷ったときの手助けになればと思います。

スタイルコンポーネント

スタイルを提供するコンポーネントです。
bordercolor等見た目に関わる要素を持たせます。

レイアウトコンポーネント

レイアウトを提供するコンポーネントです。
flexの設定やmargin等レイアウトに関わる要素を持たせます。

<!-- 以下に上げるclassはtailwindcssに準拠します -->
<template>
  <div class="flex flex-col items-start">
    <div class="w-full">
      <slot name="header" />
    </div>
    <div class="w-full">
      <slot name="content" />
    </div>
  </div>
</template>

機能コンポーネント

機能を提供するコンポーネントです。
動きや制御に関わる要素を持たせます。
これはスクリプトのみの記述で完結する事があるので、Vue3ではComposition APIを使えばコンポーネントを作る必要すら無いかもしれません。

function useRequestButton(action: () => Promise<void>) {
  const disabled = ref(false);

  async function onClick() {
    try {
      disabled.value = true;
      await action();
    } finally {
      disabled.value = false;
    }
  }

  return {
    disabled,
    onClick,
  };
}

単一フィールド入力コンポーネント

特定の項目専用に作られた入力コンポーネントです。
選択リストのような入力項目は項目ごとに表示名、順序、値の要素を持つため専用のコンポーネントに切り出します。

表示コンポーネント

シンプルな表示処理を行うコンポーネント

入力フォームコンポーネント

入力フォームとなるコンポーネント
新規登録、編集画面等で使います。
新規登録、編集では同じ項目を要求することが多いので、基本的にどちらでも使えるようにします。

表示切り替えコンポーネント

条件により表示するコンポーネントを切り替えるコンポーネント
例えば参照モード、編集モードと切り替えを実現するときに利用します。

<template>
  <ComponentA v-if="type==='a'" />
  <ComponentB v-else-if="type==='b'" />
  <ComponentC v-else-if="type==='c'" />
</template>

リストアイテムコンポーネント

v-forで繰り返すコンポーネントです。
テーブルの1行等がこれに当たります。
表示するデータが多くなるとコンポーネントを切り出さないと管理が大変になります。

Organismsコンポーネント

Atomicデザインから名前を借りました。
ある程度のまとまりを持ったコンポーネントです。
画面のデザインからある程度まとまっていると感じる要素をまとめます。

ページコンポーネント

ページの大元になるコンポーネントです。
Routerに登録するのはこのコンポーネントです。
最終的にはここにすべてが集約されます。