Vue3の基本構文③

Vueの構文についてコードベースで簡単にまとめます。
ちなみにシリーズ最終回です。
[基本構文①](https://qiita.com/takayuki-nakamura/items/86b763b2405384554017)
[基本構文②](https://qiita.com/takayuki-nakamura/items/21c2a776d882b3b12930)

今回は以下の2つです。

- コンポーネントとProps
- コミュニケーティングevent

#コンポーネントとProps
コンポーネントとは構成要素を意味し、再利用可能なVueインスタンス要素のことです。
Webページ構成する様々な要素、例えばヘッダーやサイドバーなどを分割し、コンポーネント化することで、設計・開発・テストがコンポーネント単位で行えるようになったりというメリットがあります。
そして、コンポーネントには親コンポーネントと子コンポーネントがあり、親コンポーネントから子コンポーネントに値を渡す際に使用されるのがpropsです。

```javascript:main.js
const app = Vue.createApp({})

app.component('programming', {
  props: ['title'],
  template: `<h4>{{ title }}</h4>`
})

app.mount('#component-demo')
}
```
Vueコンポーネントを作成し、その中でprops(`title`)をVueインスタンスの`data`の様に定義します。上のコードから分かる様に、テンプレートから`props`で定義した値にアクセスすることができます。

```index.html
<div id="component-demo" class="demo">
  <programming title="Angular"></programming>
  <programming title="React"></programming>
  <programming title="Vue"></programming>
</div>    
```
コンポーネント側で`props`が登録されたので、引数としてdata(`title`)をコンポーネントに送ることができます。

![Screen Shot 2020-10-24 at 18.39.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321545/b1556bfe-2fd5-8fad-ccaf-3a73537c6e52.png)

###実践的な使われ方
```javascript:main.js
const App = {
    data() {
      return {
        languages: [
          { id: 1, title: 'Angular' },
          { id: 2, title: 'React' },
          { id: 3, title: 'Vue' }
        ]
      }
    }
  }
  
const app = Vue.createApp(App)
  
app.component('programming', {
  props: ['title'],
  template: `<h4>{{ title }}</h4>`
})
  
app.mount('#component-demo')
```

```index.html
<div id="component-demo">
  <programming
    v-for="language in languages"
    :key="language.id"
    :title="language.title"
   ></programming>
</div>  
```
上記のようにVueインスタンスの`data`の中で配列で定義し、htmlで`v-for`を使いレンダリングする方法が実際のアプリケーションでよく見られます。また、`v-bind`を使用することで`props`をダイナミックに渡すことができます。

#コミュニケーティングevent
コミュニケーションは親コンポーネント->子コンポーネントだけではなく、子->親でもできます。
試しに子コンポーネントのボタンクリックから親にあるメソッドを走らせて、`color`プロパティーを変更します。

```javascript:main.js
const App = {
    data() {
      return {
        languages: [
          { id: 1, title: 'Angular' },
          { id: 2, title: 'React' },
          { id: 3, title: 'Vue' }
        ],
        languageColor: "black"
      }
    }
  }
```
Vueインスタンスの`data`に`languageColor`プロパティーを追加。

```index.html
<div :style="{ color: languageColor }">
  <programming
    v-for="language in languages"
    :key="language.id"
    :title="language.title"
  >
  </programming>
</div>   
```
htmlでスタイルの`color`を追加

```javascript:main.js
app.component('programming', {
  props: ['title'],
  template: `
  <h4>{{ title }}</h4>
  <button>
    赤色に変更
  </button>
  `
})
```
テンプレートにボタンを追加。現状はまだボタンが機能しない。

```index.html
<programming
  v-for="language in languages"
  :key="language.id"
  :title="language.title"
  @change-color="languageColor = 'red'"
>
</programming>
</div>   
```
html側で`v-on`もしくは`@`を使うことで子コンポーネントのイベントをリッスンすることができます。`@`を使用して`change-color`メソッドの実装する。

```javascript:main.js
<button @click="$emit('change-color')">
  赤色に変更	
</button>
```
子コンポーネントから親にイベントを発行してくれる`$emit`を使います。すると、親であるhtmlでイベントを受け取りリスナーの`change-color`メソッドを実行し、以下の様に`title`が赤くなりました。

![qiita pic1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321545/bcea9454-7920-17bc-8d1d-20f376724142.gif)

#おわりに
シリーズ三回に分けてVue3の基本構文を紹介してきました。Vue2とほとんど変わらないものばかり紹介してきましたが、これからもVue3を勉強してアウトプットしていきたいと思います。