LoginSignup
2
2

More than 3 years have passed since last update.

Vue2 コンポーネントまとめ ①

Last updated at Posted at 2021-04-27

はじめに

Vue.jsを勉強していてコンポーネントって大事そうなんだけど、いまいちよくわかっていないので
手を動かしながら学んだことの備忘録
Vue3もリリースされていますが、今回はVue2についてです。


Vue.jsコンポーネントとは

// button-counter と呼ばれる新しいコンポーネントを定義します
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

コンポーネントは名前付きの再利用可能な Vue インスタンスです。この例の場合、です。このコンポーネントを new Vue で作成されたルート Vue インスタンス内でカスタム要素として使用することができます。
(Vue.js公式より引用)

ふむふむ。再利用できるインスタンスかあ。Railsでいうと、ヘッダーとかフッター、サイドバー、フォームなどを_form.html.erbなどでrenderメソッドで呼び出したりしますがそんな感じってことですね。

これにより開発、メンテナンスの効率が格段に上がるとのことです。


コンポーネントの設計

コンポーネントの作り方

javascript
Vue.component('コンポーネントの名前',{
  template  :  'HTMLに表示させたい内容'
})

ちなみにVue3はこんな書き方になるようです。

Vue.createApp({

    // 省略

})
.component('コンポーネントの名前', {
    template: 'HTMLに表示させたい内容'
})
.mount('#app');

今回は特に説明はしません。Vue3でやるとエラーになることだけご理解ください。
またコンポーネントの名前はケバブケース(hello-world)またはパスカルケース(HelloWorld)とする必要があります。

コンポーネントの例

Vue.component('hello-world', {
  template : '<h1>Hello World</h1>'
})

これでhello-worldというコンポーネントができました。
これをVueインスタンス下にあるhtmlから直接コンポーネントを利用することができます。
コンポーネント作成時に登録した名前のタグを組み込みます。
今回はとid='app'として進めていきます。

See the Pen Vue.js vueコンポーネント練習1 by morioka (@rm5912) on CodePen.

html
<div id="app">
  <hello-world></hello-world>
</div>
javascript
Vue.component('hello-world',{
  template : '<h1>Hello World</h1>'
})

new Vue({
  el: '#app'
})

コンポーネントの定義はnew Vueよりも前に記述する必要があります。
new Vueのあとに定義した場合はエラーになり、
ページに何も表示されなくなります。


コンポーネントの再利用

コンポーネントの特性と言っていい、再利用。
hello-worldのタグを複数記述するだけで同じ内容を表示させることができます。

See the Pen Vue.js vueコンポーネント練習2 by morioka (@rm5912) on CodePen.


グローバルコンポーネントとローカルコンポーネント

コンポーネントは2種類あります。
グローバルコンポーネントとローカルコンポーネントです。
今まで説明してきたのはグローバルコンポーネントでVue.componentを使う場合はグローバルへの登録になり、別のコンポーネントで利用することができます。

ある特定のコンポーネントだけで利用したい場合はローカルで登録し、利用することができます。
ローカルへの登録はVueインスタンスにcomponentsプロパティを追加することで行います。

javascript
var app = new Vue({
  el: '#app',
  data: {
  },
  components: {
    'hello-world': {
      template: '<h1>Hello World</h1>'
    }
  }
})  


グローバルとローカルの違い

See the Pen Vue.js vueコンポーネント練習3 by morioka (@rm5912) on CodePen.

javascript
Vue.component('hello-world',{
  template : '<h1>Hello World</h1>'
})

var app1 = new Vue({
  el: '#app1'
})

var app2 = new Vue({
  el: '#app2',
  components: {
    'hello-vue': {
      template: '<h1>Hello Vue.js</h1>'
    }
  }
})
html
<div id="app1">
  <h2>App1</h2>
  <hello-world></hello-world>
  <hello_vue></hello_vue>
</div>

<div id="app2">
  <h2>App2</h2>
  <hello-world></hello-world>
  <hello-vue></hello-vue>
</div>

1つ目のapp1のVueインスタンスではapp2にローカル登録したhello-vueが利用できないため
Hello Vue.jsが表示されていませんが、ローカル登録されたapp2には表示されています。


templateに複数のタグ

Vue3では制限がなくなっているようですが、Vue2の場合複数のタグをtemplateに入れる場合には
注意が必要です。
どうやらコンポーネントテンプレートは1つのルート要素を持たなければならないという規則があるようです。

javascript
Vue.component('hello-world',{
  template: '<p>{{ message }}</p><p>Hello World</p>',
  data: function(){
    return {
      message : 'Hello Vue'
    }
  }
})

この場合2つ目のHello Worldが表示されていません。

See the Pen Vue.js vueコンポーネント練習4 by morioka (@rm5912) on CodePen.

pタグが2つ挿入されているため、1つのルート要素になっていなく2つのルート要素になっているからです。
そのため、この2つのpタグを含む上位のタグをつける必要があります。(divなど)
上位タグをつけることで1つのルート要素になり、2つのpタグはdivの子要素となりHello Worldも表示されるようになります。

javascript
Vue.component('hello-world',{
  template: '<div><p>{{ message }}</p><p>Hello World</p></div>',
  data: function(){
    return {
      message : 'Hello Vue'
    }
  }
})  

See the Pen Vue.js vueコンポーネント練習5 by morioka (@rm5912) on CodePen.


コンポーネントでdataを使う

コンポーネントでもdataプロパティは使えるのですが
dataは関数にする必要があります。

javascript
Vue.component('hello-world',{
  template: '<h1>{{ message }}</h1>',
  data: function(){
    return {
      message : 'Hello Vue'
    }
  }
})

複数のdataを取り扱う場合

javascript
data: function(){
    return {
      message : 'Hello Vue',
      message2 : 'Hello World'
    }
  }

dataを関数にすることでdataを持つ複数のコンポーネントを使った場合に
コンポーネントごとにdataの独立の値を保持することができます。


コンポーネントでmethodsを使う

コンポーネントはdataプロパティだけでなくmethodsプロパティも使うことができます。
ボタンを押すとアラートが表示されます。

javascript
Vue.component('hello-world',{
  template:
    '<button v-on:click="alert">アラート</button>'
  ,
  methods: {
    alert: function(event) {
      alert("アラートが表示されました")
    }
  }
})  

var app1 = new Vue({
  el: '#app1'
})

See the Pen Vue.js vueコンポーネント練習6 by morioka (@rm5912) on CodePen.


コンポーネントを複数作成した場合の独立性

コンポーネントは再利用できることを学びました。
コンポーネントを複数作成した場合はそれぞれが独立したものとして作成されます。

See the Pen Vue.js vueコンポーネント練習7 by morioka (@rm5912) on CodePen.

Upボタンでカウントが増えてDownボタンでカウントが減りますが、3つのコンポーネントは独立した状態で動作しているのがわかります。

template内のhtmlを改行する

templateに記述するhtmlは当然長くなることが多くなります。その場合シングルクオーテーションではエラーになり表示されません。

javascript
Vue.component('hello-world',{
    template: '<p>ロレム・イプサムの嘆き、トマト大好き学部のエリット、しかし時と活力、そのような労働と悲しみ、ブラインド行うにはいくつかの重要な事柄に座ります。
              長年にわたり、私は学区と長寿であれば、そのような刺激の取り組み、彼女のうち、運動の利点を分注を邪魔されたする人が来ます。
              クピダタットのつるの痛みになりたい宿題に、批判されてきたら痛み、マグナ逃亡しても結果の喜びを生成しません。先例クピダタットブラックは先例していない、つまり、彼らはあなたの悩みに責任がある人の、一般的な義務を捨て、魂を癒しています。</p>'
})  

var app = new Vue({
  el: '#app'
})

See the Pen Vue.js vueコンポーネント練習8 by morioka (@rm5912) on CodePen.

何も表示されていません。

templateで設定するhtmlが長い場合はバッククォートを使います。(``)
バッククォートで囲むと改行を行っても表示されています。

See the Pen Vue.js vueコンポーネント練習9 by morioka (@rm5912) on CodePen.

javascript
Vue.component('hello-world',{
    template: `<p>ロレム・イプサムの嘆き、トマト大好き学部のエリット、しかし時と活力、そのような労働と悲しみ、ブラインド行うにはいくつかの重要な事柄に座ります。
              長年にわたり、私は学区と長寿であれば、そのような刺激の取り組み、彼女のうち、運動の利点を分注を邪魔されたする人が来ます。
              クピダタットのつるの痛みになりたい宿題に、批判されてきたら痛み、マグナ逃亡しても結果の喜びを生成しません。先例クピダタットブラックは先例していない、つまり、彼らはあなたの悩みに責任がある人の、一般的な義務を捨て、魂を癒しています。</p>`
})  

var app = new Vue({
  el: '#app'
})


終わりに

コンポーネントについてまとめてみました。
まだまだありますがとりあえずはここら辺で①を終わりにします。
気づいたことありましたら教えていただけるとありがたいです。
②に続きます。

参考サイト
Vue.js公式サイト
REFFECT vue.jsコンポーネントの基礎
Qiita Vue】単一ファイルコンポーネントの命名規則まとめ【ファイル名から記法まで】

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2