Vue.jsで再利用可能なタブのUIコンポーネントを実装する方法を解説

タブは、Webサイトやスマホアプリでよく使用されるUIコンポーネントです。TailwindCSSやBootstrapなどのライブラリにも必ずありますが、再利用可能な柔軟性のあるものではありません。

スタイルを簡単にカスタマイズできる再利用可能なタブコンポーネントをVue.jsで実装する方法を紹介します。

再利用可能なタブのUIコンポーネントをVue.jsで実装する方法を解説

How to Build a Tab Component In Vue.js
by Luca Spezzano

下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。

はじめに

タブはUIでよく使用されるコンポーネントの1つで、Bootstrapのような人気のあるCSSフレームワークやTailwindUIのようなUIコンポーネントのライブラリにも必ずあります。

タブにはさまざまなスタイルがありますが、主な役割はページにとどまりながらタブをクリックするだけでコンテンツを変更することです。

タブのコンポーネント

タブのコンポーネント

私はプロジェクトでBootstrapのタブを使用していましたが、Vue.jsTailwindCSSを使い始めてからは、タブのコンポーネントを一から開発する方法を考えなければなりませんでした。

Vue.jsを使用してタブを実装するのは非常に簡単ですが、カスタマイズができる柔軟性を持った再利用可能なコンポーネントを実装するのは複雑です。

この記事では、再利用可能なタブのコンポーネントを実装する方法を段階的に解説します。

実装の概要

私は、2つのデモを用意しました。
1つはこの記事で解説するスタイルなしのデモと、もう1つはCodesandboxにアップロードしたTailwind CSSを使用してより美しくしたデモです。

この記事ではCSSスタイルはなしで、機能にフォーカスしています。(タブを水平・垂直に配置するためのCSSのクラスが1つだけあります)。

CSSのクラスが追加されたバージョンを確認したい場合は、デモページをご覧ください。

AppTabs.vueコンポーネントの作成

まずは、コアコンポーネントとなるAppTabs.vueを作成します。

コードの解説

上記のコードを解説します。

Propsとnamed slots

このコンポーネントでは、親がコンテンツを選択することができます。タブ(ナビゲーションリンク)はprop tabList経由で、コンテンツnamed slots経由で指定します。

named slotsは、indexのおかげでtabList内に存在する要素の数に基づいて、動的な名前で生成されます。

named slotsを自動生成するという解決策にたどり着いたのは、同僚のLuca Stefano Sartoriとの会話がきっかけでした。

named slots(名前付きSlots)の詳細については、下記をご覧ください

サイトのキャプチャ

The Difference Between Props, Slots and Scoped Slots in Vue.js
翻訳版: Vue.jsでSlotsの代わりにPropsを使用する理由、名前付きSlotsやスコープ付きSlotsとの違いについて解説

唯一の要件はtabListの数がnamed slotsと同じであることです。

ご覧のように、variantというpropもあり、これはコンポーネントが受け取ったpropに基づいて1つのCSSクラスを動的に適用することで、コンテンツの配置を変更することができます。デフォルトでは、このpropverticalです。

v-model

最初は、radio(ラジオボタン)の代わりにbuttonを使おうと思っていました。確かにその方が適切でしたが、変数に値を代入するためのコードをさらに書くことになってしまいました。その後、同僚と再び話しているうちに、この動作はv-modelを使用して自動的に再現できることがわかりました。

ユニークなid

なぜこのコンポーネントで_uid変数が使用されているのかというと、理由は簡単で、HTMLタグに固有の属性を持たせることができるからです。これにより、同じページでこのコンポーネントを何度も使用しても問題はありません。

コンポーネントの使用方法

このコンポーネントの使用方法を見てみましょう。
App.vueというページ内で使用します。

このコンポーネントは非常に簡単に使用できます。
必要なのは、このコンポーネントに、

  • タブの配列: tabList
  • named slotsを持つさまざまなタブのコンテンツ: tabPanel-${index}indextabList配列のindex + 1に相当します。

水平レイアウトを使用したい場合は、下記のようにコンポーネントにvariantを追加します。

終わりに

タブを実装するためのUIライブラリは数多くあります。しかし、これらのライブラリは必要でしょうか?

多くのライブラリは柔軟性に欠け、アプリのサイズを大きくしてしまいます。

モーダル、タブ、ドロップダウンなどのコンポーネントをゼロから実装することは、プロジェクトに最適なソリューションになることが多々あります。

実際の動作は、下記でご覧ください。

サイトのキャプチャ

デモページ

sponsors

top of page

©2021 coliss