Vue.jsのコンポーネントについて勉強してみた！備忘録【基本編】

# はじめに
最近は、JavaScriptの文法について、投稿していたのですが、今日は、Vue.jsでポートフォリオサイトを作っていて直面した知らなかったことについて勉強してみました。
作成中のポートフォリオサイト自体は、Vue CLIで作成しているのですが、作る時に、コンポーネントについて学習する必要を感じたので、テキストの読まずにすっ飛ばした章を読んでいき、それをここでちょっと備忘録としてまとめてみます！
(すっ飛ばしたのは、さっさと開発に移りたかったから...)

今日は、いつも以上に強調させて頂きます、 **備忘録です！！**
テキスト読みながらメモした、自習ノートのような感覚で見てくださった方が良いかと思います！

# コンポーネントとは
ページを構成する部品。UI部品。
掲載する内容が多くなればなるほど、コードが複雑になってきて、見づらくなってしまいます。しかし、構成部品をそれぞれ、コンポーネントに分割し、それらを組み合わせてページを作成していくことにより、見やすく、再利用もしやすくなります。また、修正の時も、該当のコンポーネントに移動することで簡単にできるようになります。

コンポーネントを利用する際には、componentメソッドを使います。

```
// 定義
	Vue.component(コンポーネント名, { 定義情報 });
```

例)

```
Vue.component('myHello', {
	template: `<div>Hi, {{ name }}!</div>`,
	data: function() {
		return {
			name: 'Vue.js'
		};
	}
});
```
上記のように、表示に必要なものをcomponentsメソッドに追加。

コンポーネントを利用する時には、画面で表示する要素を、
<template></template>で括って表します。ただし、

> テンプレート内では、これまでと同じく、{{ … }}構文やディレクティブも利用できますが、一点だけ単一のルート要素を持たなければならない点に注意してください。  
山田祥寛著『これからはじめるVue.js実践入門』(2019)p.145より引用

この、**単一のルート要素を持たなければならない**とは何か？
これは、以下のように、テンプレート内の要素をdivタグなどで括ること。
Reactを扱ったことがある方はおなじみの形式ですよねー！

```
<template>
	<div>// このdivタグが単一のルート要素
		// 任意の内容
	</div>
</template>
```

# propsと$emitメソッド
コンポーネントで定義された、dataやmethodsなどの情報は、そのコンポーネントでしかアクセスできません。
つまり、コンポーネント間で値の受け渡しが必要な場合は、特別な処理が必要になってくるのです。
(語弊があるかもしれないです。読み進めて見てください！！)
それは、以下の3種類があります。

* **プロパティ→親コンポーネントから子コンポーネントへ**
* **カスタムイベント→子コンポーネントから親コンポーネントへ**
* Vuex→アプリ全体の状態管理
3つ目のVuexに関しては、全体を通しての話になってくるので、ここでは割愛させて頂きますね。

プロパティver.(props利用)
React使ったことがある方おなじみ、props!

```
// sample.html
<div id='app'>
	<MyHello your-name='鈴木'></MyHello> // こっちはケバブケースで書く
</div>
```

```
// sample.js
Vue.Component('MyHello', {
	props: [ 'yourName' ], // こっちはキャメルケースで書く
	template: `<div>こんにちは{{ yourName }}さん</div>`
}}
new Vue({
	el: `#app`
});
```
属性値(上記では、鈴木)は、文字列としてされます。仮に数字を入れたとしても、文字列扱いされます。v-bindを使ったら、数字、またはその他のオブジェクトとして扱わせることが可能です。

propsの値の型を指定することも可能!?

```
// 略
props: {
	yourName: {
		type: String, // データ型の指定
		required: true, // プロパティが必須かどうか
		default: xxx // 値が指定されなかった時の既定値
	}
}
// 略
```
上記のように、typeでデータ型を文字列にするか数値にするかなどをあらかじめ指定することが可能です。typeやrequired、defaultを検証ルールといいます。
既定値として配列やオブジェクトを渡す場合は、既定値をreturnする関数を渡しましょう。
また、検証ルールはオリジナルのものも適用できます。

```
// 略
props: {
	yourName: {
		type: String,
		required: true,
		validator: function(value) {
			return value.length <= 5;
		}
	}
}
// 略
```
上記の例では、yourNameプロパティを5文字以内にするように規定しています。

カスタムイベントver.($emitメソッド利用)

```
// emit_sample.js
Vue.component('my-counter', {
	props: [ 'step' ],
	template: `<button type="button" v-on:click="onclick">
		{{ step }}</button>`,
	methods: {
		onclick(): {
			this.$emit('plus', Number(this.step));
		}	// 'plus'のようなイベント名は、ケバブケースのみ可能
	}
});

new Vue({
	el: '#app',
	data: {
		current: 0
	},
	methods: {
		onplus: function(event) {
			this.current += event; // eventには増分値が格納されている
		}
	}
});
```
```
// emit_sample.html
<div id='app'>
	<p>カウント：{{ current }}</p>
	<my-counter step='1' v-on:plus='onplus'></my-counter>
	<my-counter step='2' v-on:plus='onplus'></my-counter>
	<my-counter step='-1' v-on:plus='onplus'></my-counter>
</div>
```
上記のhtmlのように、v-onディレクティブ(省略系：@)を使って、plusイベントを受け取ったら、onplusメソッドを実行させるようになっています。

ポートフォリオサイトの作成では、Vue CLIを使ってしまったので、正直、今のところ、馴染みないなーっていう印象が強いのですが、基礎編はこんな感じの内容でした！
(スロットなど、一部、省略しておりますが...)

次は応用編になります！
理解不足による不備等ございましたら、コメントお願い致します。

# 参考文献・資料

山田祥寛著『これからはじめるVue.js実践入門』(2019)

Vue.js公式ドキュメント(日本語ver)
https://jp.vuejs.org/v2/guide/components.html