#はじめに
vue.jsをまた基礎から学びなおしているのですが、コンポーネントがなかなか理解した!と自信を持って言えないところです。
公式ドキュメントに沿って覚えたことを自分用解説つきで書いていきます。
#コンポーネントとは
コンポーネントシステムは Vue.js におけるもうひとつの重要な抽象概念です。「小さく、自己完結的で、(多くの場合)再利用可能なコンポーネント」を組み合わせることで、大規模アプリケーションを構築することが可能になります。アプリケーションのインターフェイスについて考えてみると、ほぼすべてのタイプのインターフェイスはコンポーネントツリーとして抽象化することができます
例えば、webページに共通のヘッダーフッターをすべてのページに出すとき、すべてのファイルにHTML分ちまちま書いたりしたくないですよね。このヘッダーフッターを再利用できるパーツ(再利用可能なコンポーネント)にしちゃおう!という感じです。
#簡単なコンポーネントを作って表示してみる
文字読んでてもよくわからないので一旦作ってみます。
サイトでよく見る、会社名と選択中のタイトル(見出し)を表示するやつをコンポーネント化してみます。
※コンポーネントの理解が主目的なので文言やデザインは超適当です。
componentsの直下にHeader.vue
を作成します
<template>
<div class="header">
<h1>会社名</h1>
<span>見出し</span>
</div>
</template>
<script>
export default {
name: 'Header',
}
</script>
<style scoped>
.header {
background-color: #2fa16e;
color: aliceblue;
}
</style>
この作ったコンポーネントを使用してみます。今回はIndex.vue
というファイルで使用します
<template>
<div id="app">
<Header/> // 3
</div>
</template>
<script>
import Header from './components/Header.vue' // 1
export default {
name: "Index",
components: {
Header // 2
},
}
</script>
1.Header.vue
をimportします。importしたものをここではHeader
と呼ぶよ。という記述
2.Header
をコンポーネントとして扱ういますという記述
3.実際に使用
という感じです。
親:Index.vue
子:Header.vue
の関係になります。
作成したHeader.vue
コンポーネントが表示されました。
##使用するコンポーネント名を変えたいとき
先ほどの書き方ではHeader.vue
をHeader
という名前としてimportして使用しましたが、<>
内での名称を変更することができます。
<template>
<div id="app">
<HeaderName/>
</div>
</template>
<script>
import Header from './components/Header.vue'
export default {
name: "Index",
components: {
"HeaderName": Header //ここを変更
},
}
</script>
Header
をコンポーネントとして使用するときはHeaderName
という名前とするよ、という記述です。
それ以外の関数でHeader.vue
使用する場合はそのままHeader
となります。
#プロパティを受け取れるようにする【props】
先ほどの例では「会社名」「見出し」の文言が固定でしたが、文言をページごとに変えたい場合も多いと思います。
props
を使用することで親のスコープから子コンポーネントへとデータを渡せるようにできます。
試しに先ほどの例の「見出し」を変えられるようにしてみます。
##子コンポーネントの書き方
<template>
<div class="header">
<h1>会社名</h1>
<span>{{ title }}</span>
</div>
</template>
<script>
export default {
name: 'Header',
props: {
title: String
}
}
</script>
---以下略---
{{ title }}
でtitleにセットされた値を受け取れるようにします。
では実際titleに何をいれるのか?
通常dataにtitleを定義しますが、今回titleに何が入るか決めるのは親でないといけません。そのため親からデータをもらえるようprops
を使用します。今回は文字列をもらうのでtitle: String
としています。
###補足1
以下のように書いても同じ動きになります。
<script>
export default {
name: 'Header',
props: {
title: {
type: String
}
}
}
</script>
###補足2
補足1のような書き方をすることで他の項目も定義できます。
<script>
export default {
name: 'Header',
props: {
title: {
type: String,
default: 'デフォルト', //デフォルト値
required: true //必須
}
}
}
</script>
##親コンポーネントの書き方
<template>
<div id="app">
<HeaderName title="見出し1"/>
<HeaderName title="見出し2"/>
</div>
</template>
<script>
import HeaderName from './components/Header.vue'
export default {
name: "Index",
components: {
HeaderName
},
}
</script>
title="見出し1"
と渡す値を指定することができます。
わかりやすいように2つ並べてみました。
実行結果
#プロパティに変数を渡す【props + v-bind】
propsで値を受け取れるようにしましたが、固定でなく変数を渡したい場合は以下のようにv-bindを使用します。
子コンポーネントはそのままで問題ありません。親を修正します。
<template>
<div id="app">
<HeaderName title="見出し1"/>
<HeaderName title="見出し2"/>
<HeaderName v-bind:title="title"/> --追加
</div>
</template>
<script>
import HeaderName from './components/Header.vue'
export default {
name: "Index",
components: {
HeaderName
},
data() {
return {
title: "見出し3",
}
},
}
</script>
v-bind:prop名="データ名"
で変数を渡せます。
省略した場合は:prop名="データ名"
となります。
##v-forを使用するとき
v-forでちょっと悩んだので書き方メモ。
###子コンポーネントの書き方
<template>
<div>
<li>{{ menu.name }}</li>
</div>
</template>
<script>
export default {
name: 'Header',
props: {
menu: Object
}
}
</script>
###親コンポーネントの書き方
<template>
<div id="app">
<Header v-for="menu in menus"
:key="menu.name"
:menu="menu"/>
</div>
</template>
<script>
import Header from './components/Header.vue'
export default {
name: "Index",
components: {
Header
},
data() {
return {
menus: [
{
name: "メニュー1"
},
{
name: "メニュー2"
},
{
name: "メニュー3"
},
]
}
},
}
</script>
#さいごに
ドキュメントよみながら思い出しながら進めているので補足などあれば随時更新していきます。
また、なにか間違いやこうしたほうがいいよ等何かあればコメントいただけると嬉しいです。
最後まで読んでいただきありがとうございます!