【Vue.js】コンポーネントの基本的な説明と書き方

Vueのコンポーネントの基本的な書き方を学んだので、学習したところまで簡単にまとめます。
javascriptでvueが使えるものとします。

*参考文献*
*Vue.js開発入門*
*Vue.js入門*

##コンポーネントとは
![components.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429297/2091094b-58c1-2eac-d541-78269817673b.png)
コンポーネントを使うと同じような処理を行う部分を部品としてまとめることができます。
開発の規模が大きくなってきた時に役立ち、同じような見た目や機能を持つもの、他のページでも利用できるものなど、繰り返し利用でき、開発の効率化や品質保持、保守性の向上に繋がります。

###コンポーネントの定義
用途に応じてグローバルコンポーネントとローカルコンポーネントを定義できます。
ですが、グローバルに定義するのはあまり理想的ではなく、トラブルやコードの複雑化を生んでしまうからです。
ですので、ここではローカルコンポーネントで進めます。

####ローカルに定義の例

```html:index.html
    <div id="app">
        <!-- コンポーネントのタグ名 -->
        <my-component></my-component> <!-- Hello -->
        <my-component></my-component> <!-- Hello -->
        <my-component></my-component> <!-- Hello -->
    </div>
```

```javascript:main.js

// let コンポーネントのオブジェクト名 = {
//      オプション:　オプションの内容
//}

// let vm = new Vue({
//      el: '#id名など', 
//      components: {
//          'コンポーネントのタグ名': コンポーネントのオブジェクト名
//      }
// })

  let MyComponent = {
       template: '<p>Hello</p>',
  }

  let vm = new Vue({
       el: '#app', 
       components: {
           'my-component': MyComponent
       }
  })
```
このように、コンポーネントはマウント前に定義します。
**名前の書き方に注意が必要で、コンポーネントのオブジェクト名はパスカルケース、コンポーネントのタグ名はケバブケースで書きます。**

次の例では先ほどのHTMLはそのままで、コンポーネントにdataとmethodsを追加し、クリックすると数値が１増える機能を持ったボタンを作ります。

```javascript:main.js
let MyComponent = {
     template: `
     <p>カウンター<button v-on:click="addOne">add</button>{{ count }}</p>
     `,
     data: function() {
          return {
               count: 0
          }
     },
     methods: {
          //ボタンを押すと１追加する
          addOne: function() {
               this.count++;
          }
     }
}

let vm = new Vue({
     el: '#app', 
     components: {
         'my-component': MyComponent
     }
})
```
ここで大事なのは、３つのボタンがそれぞれ独立しており値を保持しているということです。
dataを見ていただけるとわかると思いますが、**dataは関数で定義しなければなりません。**
これは、dataをオブジェクトとして使おうとすると、コンポーネントの全てのインスタンスでdataが共有されてしまうからです。
上の例で言うと、３つのボタンのうち１つを押すと、３つともカウントされてしまうと言うことです。
##props 【親コンポーネントから子コンポーネントにデータを渡す】
書式： `props: {プロパティ名（親から受け取る属性名）: データ型、真偽値など}`

コンポーネントはHTMLタグから値を受け渡すことができます。
親から子へデータを渡す時に、propsを使います。
propsオプションでも名前の書き方に注意が必要で、propsオプション内のプロパティはキャメルケース、HTMLのタグ内ではケバブケースで書きます。

次の例では、v-forでコンポーネントを繰り返し、propsはテンプレートの属性v-bind経由でHTMLから値を渡し表示します。

```html:index.html
    <div id="app">
        <my-component v-for="(item, index) in myArr" :my-name="item" :my-number="index"></my-component>
        <!--私は一郎です。1番です。
            私は二郎です。2番です。
            私は三郎です。3番です。
            私は四郎です。4番です。
            私は五郎です。5番です。-->
    </div>
```

```javascript:main.js
let MyComponent = {
     template: '<p>私は{{ myName }}です。{{ myNumber + 1}}番です。</p>',
     props: {
          myName: String,
          myNumber: Number
     },
     created: function() {//値が渡ったかチェック。インスタンスが生成された後に実行される
          if(!this.myName) {
              this.myName = "名無し";
          }
     }
 }

let vm = new Vue({
     el: '#app',   
     data: function() {
          return {
               myArr: [
                    '一郎',
                    '二郎',
                    '三郎',
                    '四郎',
                    '五郎'
               ]
          }
     },
     components: {
         'my-component': MyComponent
     }
 })
```
このように、v-forで配列から中身と番号を取り出し、そのデータをpropsを使いv-bind経由で渡し、配列の数だけコンポーネントを表示することができます。

---
今回は以上です。
学習が進み次第、更新や新しく記事を書こうと思います。
まだまだ書ききれないこともありますが、これまでで大事なところが抜けていたり訂正などありましたらご教授していただけると嬉しいです。
最後まで読んでいただきありがとうございます。