Vue.jsには、コンポーネントを制御するためのコンポーネントのメタコンポーネントの組み込みコンポーネントが用意されています。
今回は、コンポーネントを動的に切り替える組み込みコンポーネントの<component>要素について紹介します。
動的コンポーネント
動的なコンポーネントとは、ユーザーの操作やアプリケーションの状態によって、コンポーネントを切り替える仕組みです。
動的コンポーネントを使用すると、例えばタブ付きのインターフェースを持つアプリケーションで、タブがクリックされた時にタブページに表示されるコンポーネントを切り替えることができます。
<component>要素
<component>要素は、コンポーネントのコンテナとして動作します。
<component>要素はコンポーネントの入れ物として動作し、あらかじめ用意されているコンポーネントをインポートすることで、動的な切り替えを可能にします。
サンプルのコンポーネント
ここでは、タブページを持つUIを例に<component>要素を使用してコンポーネントを切り替えます。
タブページに配置するコンポーネント(インポートするコンポーネント)
タブがクリックされた時に、タブページに配置するコンポーネント(タブに対応するコンポーネント)は次のようにします。
1 2 3 |
const homeTab = { template: `<div class="tab-page">ホームのコンポーネントのコンテンツ</div>` }; |
1 2 3 |
const referenceTab = { template: `<div class="tab-page">リファレンスのコンポーネントのコンテンツ</div>` }; |
1 2 3 |
const documentTab = { template: `<div class="tab-page">ドキュメントのコンポーネントのコンテンツ</div>` }; |
タブがクリックされると、上記の3つのコンポーネントのうちのいずれかがインポートされます。
上記のコードはJavaScript側のスクリプトに実装します。
コンポーネントを呼び出すアプリケーション
用意した3つのコンポーネントを呼び出し、切り替えて表示するための呼び出し側のアプリケーションのコードを実装します。
1 2 3 4 5 6 7 8 9 10 11 12 |
<div id="app"> <!-- タブのボタン --> <button v-for="tab in tabs" v-bind:key="tab.key" v-bind:class="['tab-button', { active: currentTab === tab.key }]" v-on:click="currentTab = tab.key"> {{ tab.name }} </button> <!-- タブページのコンポーネント --> <component v-bind:is="currentTabComponent"></component> </div> |
HTMLのテンプレートにはアプリケーションのルートとなるdiv要素を配置します。
div要素の中にタブとなるボタン(button要素)を配置します。タブのボタンはv-forディレクティブを使用して描画します。
タブとなるボタンの下にタブページとなるコンポーネントを配置します。
ここでcomponent要素を使用します。component要素の属性の「is」にv-bindディレクティブを使用してインポートするコンポーネントの名前を指定します。ここで指定している「currentTabComponent」は、JavaScript側に記述するVueインスタンスのcomputedプロパティオプションに定義するデータになります。
component要素を配置した部分がコンポーネントの表示領域となり、is属性で指定した名前が表示すべきコンポーネントになります。currentTabComponentの値が切り替わることで、表示するコンポーネントが動的に切り替わります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
.tab-button { padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid #ccc; cursor: pointer; background: #f0f0f0; margin-bottom: -1px; margin-right: -1px; } .tab-button:hover { background: #e0e0e0; } .tab-button.active { background: #e0e0e0; } .tab-page { border: 1px solid #ccc; padding: 10px; } |
CSSにはタブ(のボタン)とタブページを表現するスタイルを定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// アプリケーションのVueインスタンス const app = Vue.createApp({ data() { return { currentTab: 'Home', tabs: [ { key: 'home', name: 'ホーム' }, { key: 'reference', name: 'リファレンス' }, { key: 'document', name: 'ドキュメント' } ] } }, computed: { currentTabComponent() { return 'tab-' + this.currentTab.toLowerCase() } } }) // コンポーネントの設定 app.component('tab-home', homeTab) app.component('tab-reference', referenceTab) app.component('tab-document', documentTab) // HTMLテンプレートとのマウント設定 app.mount('#app') |
JavaScript(スクリプトのプログラム)にはVueのインスタンスを定義します。
Vueインスタンスにはdataプロパティオプションとcomputedプロパティオプションを定義します。
dataにはカレントタブ(現在のタブ)の「currentTab」と、タブの情報を持つオブジェクトの「tabs」を定義します。
computedオプションには、HTMLテンプレートところで触れたコンポーネントの名前を返す関数を定義します。
上記の実装コードをブラウザーで実行(表示)すると、冒頭に掲載した画像のイメージの画面が表示されます。
タブのボタンをクリックすることで、タブページに表示されるコンポーネントが切り替わります。
「ホーム」タブがクリックされた時は「ホームのコンポーネントのコンテンツ」というテキストが表示され、「リファレンス」タブがクリックされた時は「リファレンスのコンポーネントのコンテンツ」というテキストが表示され、「ドキュメント」タブがクリックされた時は「ドキュメントのコンポーネントのコンテンツ」というテキストが表示されることが確認できます。