Vue.jsにはコンポーネント(テンプレート)という機能があります。
通常ブラウザ上に表示するHTMLのコードはhtmlファイルに記述しますが、コンポーネントにすると、Vue.jsにhtmlのコードを記述し、それに名前をつけてhtmlファイルの好きなところで呼び出すことができるようになります。
繰り返し使用する部分や、htmlファイル上に記述すると煩雑になる記述はコンポーネントとして抜き出すと、htmlファイルがスッキリし管理が簡単になります。
ここでは、グローバルコンポーネントとローカルコンポーネントの違いを含めて、コンポーネントの使い方を実例でまとめています。
コンポーネントとは何か?
そもそもコンポーネントという言葉を聞きなれないかもしれません。
コンポーネントとはお問い合わせフォームやQ&Aなど、コードの記述の一部をひとまとまりの要素として切り出したものです。
作成したコンポーネントには独自の名前を設定することができ、HTMLファイル上でその要素を呼び出したい場所に、コンポーネントの名前を記述すると、そのコンポーネントに含まれているコードを呼び出すことができます。
何度も呼び出すなど、使い回す可能性のある要素をコンポーネント化します。
グローバルコンポーネントとローカルコンポーネントの違い
コンポーネントにはアプリケーションの中ならどこでも呼び出せるグローバルコンポーネントと、指定したVueインスタンスの中でのみ呼び出せるローカルコンポーネントがあります。
テンプレート | 作成方法 |
---|---|
グローバル | Vue.componentを使って定義する。 |
ローカル | new Vueの中のcomponentsオブジェクトで定義する。 |
以下でそれぞれを実例でまとめています。
グローバルコンポーネントの作り方
始めに、アプリケーション内のどのVueでも呼び出すことができるグローバルコンポーネントの作成手順についてです。
グローバルコンポーネントの作り方
グローバルコンポーネントの作り方はとてもシンプルです。(ローカルコンポーネントも同じくしプルです)
JavaScriptのファイル(.jsファイル)に以下のように記述します。
Vue.component('コンポーネント名', {
template: 'HTMLのコード',
data():{
return{
}
},
methods:{
},
computed:{
},
})
HTMLをコンポーネント化する
コンポーネントではdataオブジェクトやmethodsオブジェクトなど、Vue.jsの記述を書くこともできますが、それ以外にも単にHTMLの要素を再利用可能なブロックとして定義することもできます。
jsファイルにコンポーネントを定義する
//コンポーネントの定義
Vue.component('コンポーネント名', {
template: 'HTMLのコード',
})
//Vueインスタンスの定義
var app = new Vue({
el:'#app'
})
以上でVueコンポーネントの作成は完了です。
HTMLファイルでコンポーネントを呼び出す
HTMLファイルで作成したコンポーネントを呼び出すには以下のようにします。
<コンポーネント名></コンポーネント名>
<body>
<div id="app">
<コンポーネント名></コンポーネント名>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
なお、コンポーネントは何度でも呼び出すことができます。
実例
HTMLのみをVueコンポーネント化して、htmlファイルで呼び出す例です。
hello-vueという名前のグローバルコンポーネントを作成します。
Vue.component('hello-vue', {
template: '<p>「こんにちは!」</p>',
})
var app = new Vue({
el:'#app'
})
htmlファイルの中で、hello-vueを呼び出します。
<body>
<div id="app">
<p>以下でVueコンポーネントを呼び出しています</p>
<hello-vue></hello-vue>
<p>呼び出しは以上です。</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
作成したVueコンポーネントが正しく呼び出されていることが確認できます。
何度も呼び出す例
作成したテンプレートは何度も呼び出すことができます。
上記の例で、HTMLファイルの中で複数回Vueコンポーネントを呼び出してみます。
<body>
<div id="app">
<p>以下でVueコンポーネントを呼び出しています</p>
<hello-vue></hello-vue>
<hello-vue></hello-vue>
<p>呼び出しを以下でも行います。</p>
<hello-vue></hello-vue>
<hello-vue></hello-vue>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
記述した場所でVueコンポーネントが呼び出されていることがわかります。
templateプロパティの値を改行する方法
templateの値をシングルクオーテーションやダブルクォーテーションで指定する場合、改行が使えないため、タグを1行で記載しなければいけません。コードリーディングが非常に見にくくなってしまいます。
templateプロパティの値で改行を使いたい場合は「`(バッククオート)」で囲みます。
バッククオートはshift + @で記述できます。
バッククオートと使うと次のような記述が可能になります。
Vue.component('hello-vue', {
template: `
<dl>
<dt>AAA</dt>
<dt>BBB</dt>
<hr>
<dt>111</dt>
<dt>222</dt>
</dl>`,
})
var app = new Vue({
el:'#app'
})
htmlファイルの中で、上記のテンプレートを呼び出します。
<body>
<div id="app">
<p>以下でVueコンポーネントを呼び出しています</p>
<hello-vue></hello-vue>
<p>呼び出しは以上です。</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
改行ありのコードもコンポーネントとして呼び出せます。
複数回呼び出す
もちろん、何度も呼び出すことができます。
<body>
<div id="app">
<p>以下でVueコンポーネントを呼び出しています</p>
<hello-vue></hello-vue>
<p>以下でも呼び出します。</p>
<hello-vue></hello-vue>
<p>3回目の呼び出し</p>
<hello-vue></hello-vue>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
コンポーネントの中でdataオブジェクトを使う方法
通常のVue.jsと同様に、コンポーネントの中でdataオブジェクトを使うこともできます。
dataオブジェクトを使えばVue側に作成したデータをテンプレートで呼び出すことができます。
基本的な書き方
コンポーネント内で、dataオブジェクトを使う書き方は次のようになります。
Vue.component('コンポーネント名', {
template: 'htmlのコード',
data(){
return {
プロパティ名1: 値1,
プロパティ名2: 値2
}
}
})
なお、上記は以下の記述の省略形です。
Vue.component('コンポーネント名', {
template: 'htmlのコード',
data: function(){
return {
プロパティ名1: 値1,
プロパティ名2: 値2
}
}
})
実例
dataオブジェクトを持ったコンポーネントを使って、templateオブジェクトの中でプロパティを呼び出します。
コンポーネント内で、dataオブジェクトを使う書き方は次のようになります。
messageとhelloというプロパティを作成し、それをtemplateの中で呼び出しています。コンポーネント名は「data-vue」としています。
Vue.component('data-vue', {
template: '<p>{{hello}} {{message}}</p>',
data(){
return {
message: "初期値のメッセージです。",
hello: "「こんにちは!」",
}
}
})
var app = new Vue({
el:'#app'
})
<body>
<div id="app">
<div>
<p>■dataを使ったコンポーネント</p>
<data-vue></data-vue>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
dataに記述したプロパティの値がコンポーネントの中で呼び出され、ブラウザ上に正しく表示されます。
コンポーネントの中でmethodsを使う方法
Vue.jsではdataオブジェクト以外にも、methods, watch, computedなど様々な便利オブジェクトが使えます。
これらはもちろんコンポーネントの中でも使えます。注意点はdataと違ってreturnは不要ということです。
data以外は基本的に同じ書き方をするので、ここでは代表としてmethodsを使った記述を紹介します。
書き方
template, dataと並列にmethodsを記述します。
methods:{ メソッド名(){ 処理 } }
Vue.component('コンポーネント名', {
template: 'htmlのコード',
data(){
return {
プロパティ名1: 値1,
プロパティ名2: 値2
}
},
methods:{
メソッド名(){
処理
}
}
})
実例
methodsを使った実例として、要素をクリックするとdataにセットした2つのプロパティをつなげて、画面上に表示するプログラムを作ります。
Vue.component('methods-vue', {
template: '<p @click="sayHi">挨拶: {{ output }}</p>',
data(){
return {
name: "AAAさん",
hello: "「こんにちは!」",
output: ""
}
},
methods:{
sayHi(){
this.output = this.name + this.hello
}
}
})
var app = new Vue({
el:'#app'
})
template: '<p @click="sayHi">挨拶: {{ output }}</p>',
HTML上で呼び出すコンポーネントは上記の部分になります。
pタグの要素をクリックするとクリックイベントが発動して、指定したメソッド sayHiを実行します。
sayHi(){
this.output = this.name + this.hello
}
sayHiはプロパティにセットされているnameとhelloの値をつなげて、プロパティoutputにセットします。
結果として、pタグ内で呼び出している {{ output }} が更新され、文字列が画面に表示されます。
htmlファイルの中で、上記のコンポーネントを呼び出します。
<body>
<div id="app">
<div>
<p>■methodsを使ったコンポーネント</p>
<methods-vue></methods-vue>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
↓ 「挨拶:」をクリック
メソッドが実行され、文字列が表示されました。
グローバルコンポーネントを複数作成する方法
コンポーネント名を変えれば、コンポーネントを複数作成することもできます。
基本的な書き方
//コンポーネントの定義
Vue.component('コンポーネント名1', {
template: 'HTMLのコード',
})
Vue.component('コンポーネント名2', {
template: 'HTMLのコード',
})
//Vueインスタンスの定義
var app = new Vue({
el:'#app'
})
実例
「hello-vue」と「dl-vue」という2つのコンポーネントを作成します。
Vue.component('hello-vue', {
template: '<p>「こんにちは!」</p>',
})
Vue.component('dl-vue', {
template: `
<dl>
<dt>「AAA」</dt>
<dt>「BBB」</dt>
</dl>`,
})
var app = new Vue({
el:'#app'
})
htmlファイルの中で、上記2つのコンポーネントをそれぞれ呼び出します。
<body>
<div id="app">
<div>
<p>複数のコンポーネントを呼び出す</p>
<hello-vue></hello-vue>
<dl-vue></dl-vue>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
ブラウザにそれぞれのコンポーネントの内容が表示されていることがわかります。
ローカルコンポーネントの作り方
どのVueインスタンスでも呼び出せるグローバルコンポーネントと違い、特定のVueインスタンスの中でした呼び出せないローカルコンポーネントを作成することもできます。
ローカルコンポーネントを使うメリットは、コンポーネントの中で定義したdataやmethodsなどがその指定したVueインスタンスの中だけで有効になることです(グローバルに影響しない)
作り方
ローカルコンポーネントはVueインスタンスの中にcomponentsオブジェクトを作成し、その中で定義します。
var app = new Vue({
el:'#app',
components: {
'コンポーネント名': {
template: 'htmlタグ',
data(){
return {}
},
methods:{},
computeds:{}
}
}
})
実例
Vueインスタンスの中にlocal-helloというコンポーネントを作成し、それをhtmlファイルの中で読み込みます。
var app = new Vue({
el:'#app',
components: {
'local-hello': {
template: '<p>{{ name }}さん。こんにちは!</p>',
data(){
return {
name: "AAA"
}
}
}
}
})
htmlファイルの中で、上記のコンポーネントを呼び出します。
<body>
<div id="app">
<p>ローカルコンポーネントの呼び出し</p>
<local-hello></local-hello>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
ローカルコンポーネントをVueインスタンスの外に記述する方法
ローカルコンポーネントをVueインスタンスの中に作成すると、コードが長く煩雑になり読みにくくなります。
このため、コンポーネントの中身は外に変数や別ファイルとして切り出し、インスタンスの中でその変数を読み込むのが一般的です。
書き方
変数として定義する場合は以下のようになります。
var 変数名 = {
template: 'htmlタグ'
data(){
return {}
},
methods:{},
computeds:{}
}
var app = new Vue({
el:'#app',
components: {
'コンポーネント名': 変数名
}
})
実例
localCompという変数を定義し、その中にVueテンプレートの内容を記述します。それをVueインスタンスのcomponentsの値として読み込みます。
components: {
'local-hello': localComp
}
jsファイルのコード全体は以下のようになります。
var localComp = {
template: '<p>{{ name }}さん。こんにちは!</p>',
data(){
return {
name: "AAA"
}
}
}
var app = new Vue({
el:'#app',
components: {
'local-hello': localComp
}
})
htmlファイルの中で、上記のコンポーネントを呼び出します。
<body>
<div id="app">
<p>ローカルコンポーネントの呼び出し</p>
<local-hello></local-hello>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
ローカルコンポーネントを複数作成する方法
グローバルコンポーネントと同じく、ローカルコンポーネントも複数作成することができます。
Vueインスタンスのcomponentsの中で複数のコンポーネントを定義します。
書き方
components: {
'コンポーネント名1': コンポーネント1の中身,
'コンポーネント名2': コンポーネント2の中身,
'コンポーネント名3': コンポーネント3の中身,
,,,,
}
実例
localCompとengHelloという変数を定義し、Vueインスタンスのcomponentsの中でコンポーネントとして読み込みます。
var localComp = {
template: '<p>{{ name }}さん。こんにちは!</p>',
data(){
return {
name: "AAA"
}
}
}
var engHello = {
template: '<p>Hello {{ name }}!</p>',
data(){
return {
name: "BBB"
}
}
}
var app = new Vue({
el:'#app',
components: {
'local-hello': localComp,
'eng-hello': engHello
}
})
それぞれのコンポーネントは独立とみなされるため、dataオブジェクトにnameプロパティを設定していますが、別物として扱われます。
htmlファイルの中で、上記のコンポーネントを呼び出します。
<body>
<div id="app">
<p>ローカルコンポーネントの呼び出し</p>
<local-hello></local-hello>
<eng-hello></eng-hello>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
それぞれのコンポーネントの内容が呼び出されています。{{ neme }} にはそれぞれのプロパティの値が入っています。
グローバルとローカルコンポーネントの併用
最後に、参考としてグローバルとローカルコンポーネントを併用したプログラムを記載しておきます。
ブラウザ上のボタンをクリックすると1づつ加算するコンポーネントです。
localCompとengHelloという変数を定義し、Vueインスタンスのcomponentsの中でコンポーネントとして読み込みます。
//■グローバルコンポーネント
Vue.component('hello-component', {
template: '<p>Hello World</p>',
})
//■dataを使ったコンポーネント
Vue.component('data-vue', {
template: '<p>{{mes1}} {{mes2}}</p>',
data(){
return {
mes1: "AAAさん。",
mes2: "こんにちは",
}
}
})
//■ボタンカウンターコンポーネント
Vue.component('button-counter', {
data() {
return {
count: 0
}
},
template: '<div><span>Please Click: <button v-on:click="count++">{{count}}</button></span></div>'
})
//■ローカルコンポーネント
var localComponent = {
template: '<p>ローカルからこんにちは!</p>'
}
var app = new Vue({
el:'#app',
components: {
'local-component': localComponent
}
})
<body>
<div id="app">
<div>
<p>■グローバルコンポーネント</p>
<hello-component></hello-component>
</div>
<br><hr>
<div>
<p>■dataを使ったコンポーネント</p>
<data-vue></data-vue>
</div>
<br><hr>
<div>
<p>■ローカルコンポーネント</p>
<local-component></local-component>
</div>
<br><hr>
<div>
<p>■ボタンカウンター</p>
<button-counter></button-counter>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
1つのページ上に、グローバルコンポーネントとローカルコンポーネントを同時に表示できます。