ここでは、componentメソッドを使ったコンポーネントの定義について紹介します。
目次
Vue.jsのコンポーネント
コンポーネントは、Vue.jsを使用して作成するアプリケーションでは非常によく利用する機能です。
コンポーネントとは、名前の付いた再利用可能な部品(オブジェクト)になります。
コンポーネントには「グローバルコンポーネント」と「ローカルコンポーネント」があります。
グローバルコンポーネントは、名前の通りグローバルに利用することができます。
ローカルコンポーネントは、特定のVueインスタンス(アプリケーション)や、コンポーネント内でのみ利用することができます。
特定のVueインスタンスでのみ利用するコンポーネントを定義する場合は、ローカルコンポーネントを使用することで、名前の重複などを気にすることなくコンポーネントを使用することができます。
ローカルコンポーネントの定義
ローカルコンポーネントはVueインスタンスのcomponentsプロパティオプションで定義できます。
1 2 3 |
<div id="app"> <custom-component v-bind:message="'Hello Vue.js!'"></custom-component> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Vue.createApp({ components: { 'custom-component': { template: '<div>{{message}}</div>', props: { message: { type: String, default: 'message', required: true } } } } }).mount('#app') |
コンポーネントを利用するVueインスタンスのcomponentsプロパティオプションに、コンポーネント名と、コンポーネントのオブジェクトを定義します。
componentメソッドを使用したコンポーネントの定義
componentsプロパティオプションを使用するとローカルコンポーネントが定義できますが、コンポーネントはVueインスタンス(アプリケーション)のcomponentメソッドを使用して設定することもできます。
上記のcomponentsプロパティオプションを使用したコンポーネントの定義をcomponentメソッドを使用する方法に変更すると次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Vueインスタンス(アプリケーション) let app = Vue.createApp({}) // コンポーネントの設定 app.component('custom-component', { template: '<div>{{message}}</div>', props: { message: { type: String, default: 'message', required: true } } }) // マウントの設定 app.mount('#app') |
componentメソッドを使用してコンポーネントを設定する場合は、先ずVueインスタンスを変数を定義して格納します。(上記の例では「let app = 」の部分)
変数に格納したVueインスタンスのcomponentメソッドを使用してコンポーネントを設定します。
componentメソッドには1つ目の引数(パラメーター)にコンポーネントの名前を指定します。2つ目の引数にはコンポーネントのオブジェクトを指定します。
(名前とオブジェクトの指定は、componentsプロパティオプションを使用する場合と同様です。)
HTML要素とのマウント(mountメソッドを使用したVueインスタンスを適用するHTML要素の指定)は、componentメソッドでコンポーネントを指定した後に行います。
上記のコードを実行すると、画面に「Hello Vue.js!」というテキストが表示されることが確認できます。
compomentsプロパティオプションとcomponentメソッドの違い
compomentsプロパティオプションを使用して設定したコンポーネントは、compomentsプロパティオプションを定義するVueインスタンスでは使用できますが、サブコンポーネントでは使用できません。
一方componentメソッドを使用して設定したコンポーネントはサブコンポーネントでも使用できます。
例えば、以下のようにcomponentメソッドを利用して設定したコンポーネントは、アプリケーションへのグローバル登録となります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const app = Vue.createApp({}) app.component('component-a', { template: '<div>A</div>' }) app.component('component-b', { template: '<div>B</div>' }) app.component('component-c', { template: '<div>C</div>' }) app.mount('#app') |
上記3つのコンポーネントはすべてが相互に使用することが可能なので、以下のようにコンポーネントのテンプレート内で別のコンポーネントを参照することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const app = Vue.createApp({}) app.component('component-a', { template: '<div>A</div>' }) app.component('component-b', { template: '<div>B<component-a></component-a></div>' }) app.component('component-c', { template: '<div>C<component-b></component-b></div>' }) app.mount('#app') |
次のようなHTMLを記述して実行すると
1 2 3 |
<div id="app"> <component-c></component-c> </div> |
画面には「C」「B」「A」の順にテキストが表示されます。
これは、「component-c」内に配置した「component-b」が描画され、「component-b」に配置した「component-a」が描画されるためです。
上記の処理をcompomentsプロパティオプションに変更すると、コンポーネントから参照しているサブコンポーネントが描画されないことが確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const componentA = { template: '<div>A</div>' } const componentB = { template: '<div>B<component-a></component-a></div>' } const componentC = { template: '<div>C<component-b></component-b></div>' } const app = Vue.createApp({ components: { 'component-a': componentA, 'component-b': componentB, 'component-c': componentC } }) app.mount('#app') |
次のHTMLを記述して実行すると
1 2 3 |
<div id="app"> <component-c></component-c> </div> |
画面には「C」のみが表示されます。
上記のようにcomponentsプロパティオプションによってローカルコンポーネントとして設定している場合は、すべてのコンポーネントを表示するためには、以下のようなHTMLを記述する必要があります。
1 2 3 4 5 |
<div id="app"> <component-c></component-c> <component-b></component-b> <component-a></component-a> </div> |