【Nuxt.js】slot基礎編：コンポーネントの一部を置き換えよう

# 前置き
Nuxt.jsと言えばコンポーネント。
componentの内容を、ページによって少しで良いから変えたい…
そんな時、slotに随分と助けられたので記録に残しました。
Vue.jsでも同様の使い方が可能です。
※サンプルテキストはHello Nuxt.js!ではなくHello Vue.js!になっていますが、ご了承ください。

間違い等がございましたら、優しくご指摘いただけると嬉しいです！

基礎編：超簡単な解説から実践編まで
応用編：全体のまとめ、propsとの違い
を書いていきます。

# slotって？メリットは？
ウェブサイトを作ってて、
「同じコードをコピペしまくってめんどいなぁ〜
　あ！コンポーネント使えばいいじゃん！！
　あれ？でもページによって○○だけ変えたいんだよなぁ」
って時、ありますよね？

コンポーネントを使いまわしたいけど、
ここの文字だけ変えたい！って時に使います。
（文字以外も変更は利きますが、今回はわかりやすく文字で例えます）

コンポーネントが使えないから、
基本のコードコピペして中身だけ編集する…
なんて面倒なことをしなくていいんです！
コンポーネントにしちゃって、一部だけ変えればいいんです！
楽ちん！！


# slotを使わない場合どうなるの？
じゃあコンポーネントを使って…親コンポーネントで中身を変えよう！
slotなくても<Component></Component>の中身に書けばよくない？
と思ったそこのアナタ！
こちらをご覧ください。

```Component.vue
Component.vue // 子コンポーネント
<div class="ItemTitle">
 <h1>ここは親ページによってタイトルを変えたい</h1>
</div>
```
```index.vue
index.vue // 親ページ
<Component>
 Hello Vue.js!
</Component>
```
```html
表示結果
<div class="ItemTitle">

</div>
```
そうなんです。。。
子のコンポーネントの中身は無視されちゃいます。
それも完全なシカトです。ツライ。。。

```vue
<Component>ここは無視される</Component>
```

# slotの使い方(超簡単ver.)
そこでslot君の登場です！！
使い方は超〜〜〜簡単。
子コンポーネント内に変えたい部分をslotにするだけ。
上の説明に使ったコードでやってみます。

【表示結果】
![picture_pc_96a0996a6f584fe201bfcad0b23a9059.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/15acf26c-39dd-803c-fede-ab7f639d6fbd.png)


```vue
<div class="itemTitle">
 <h1>Hello Vue.js!</h1>
</div>
```

【コード】

子コンポーネントだけslotを加えます。

```Component.vue
Component.vue // 子コンポーネント
<div class="itemTitle">
 <h1>
  <slot /> // ここは親ページによってタイトルを変えたい
 </h1> 
</div>

<style scoped>
.itemTitle {
 margin: 10px;
}
h1 {
 color: rgb(65, 193, 222);
}
</style>
```

親は一緒。

```index.vue
index.vue // 親ページ
<Component>
 Hello Vue.js!
</Component>
```
これだけで表示結果が変わる！！
slotくんに呼びかけて、ちゃんとデータを表示してくれます。
偉いぞslotくん！！！



# slotの使い方(複数ver.)
便利なslotくん
「じゃあいっぱいslot使おう！
　h1とh2にも使おう〜」
って場合は
各slotに名前をつけてあげる必要があります。

「これ表示して？」って言われても、
名前で呼んでくれないと、
どのslotくんが表示すればいいのか分からなくなっちゃいますよね。

そういう先輩いません？
「これやっといて〜」って、
今誰に言ったの？私やるの？？？え、誰？？？
みたいな。

なので、
もし名前をつけないでslotを2つ用意すると
親に入れたものが2回表示されます。
「はいはい、私やりますね」って2人反応しちゃいます。

名前で呼ばなかった先輩はきっと
同じ仕事を無駄に2個やらせてしまったことを後悔するでしょう。
こんなにいらんわ。。。って。

【表示結果】
![picture_pc_cd512416e11b9b6b113ed8fa8676b625.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/49236f33-8530-9751-2850-31f9d3d12b22.png)

```html
<div class="ItemTitle">
 <h1>
  Hellot Vue.js!
  about slot
 </h1>
 <h2>
  Hellot Vue.js!
  about slot
 </h2>
</div>
```

【コード】

```Component.vue
Component.vue // 子コンポーネント
<div class="ItemTitle">
 <h1>
  <slot /> // ここは親ページによってタイトルを変えたい
 </h1>
 <h2>
  <slot /> // ここは親ページによってサブタイトルを変えたい
 </h2>
</div>

<style scoped>
.itemTitle {
 margin: 10px;
}
h1 {
 color: rgb(65, 193, 222);
}
h2 {
 color: gray;
}
</style>
```
```index.vue
index.vue // 親ページ
<Component>
 Hellot Vue.js!
 about slot
</Component>
表示結果
<div class="ItemTitle">
 <h1>
  Hellot Vue.js!
  about slot
 </h1>
 <h2>
  Hellot Vue.js!
  about slot
 </h2>
</div>
```

# slotの使い方(実践ver.)
ということで各slotくんに名前をつけてあげましょう。
「◯◯くん、これ表示しといてよ」って言ってくれたら、
はい、私ですね！表示しますね！ってなりますよね。

ここで１つ注意。
名前をつける場合は、
親で<template>タグで囲う必要があります。
これさえできればもう完璧。

【表示結果】
![picture_pc_912dbfccaa95a0ce68d99cf19a889283.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/39dba151-51ed-f68f-9310-4c2b10878a9c.png)

```html
<div class="itemTitle">
 <h1 class="title">Hello Vue.js!</h1>
 <p>slotを学ぼう</p>
 <div class="catchCopy"># slotって？メリットは？</div>
</div>
```

【コード】

```ItemTitle.vue

ItemTitle.vue // 子コンポーネント
<div class="itemTitle">
 <h1>
  <slot name="title" /> // 置き換えたい部分のslot nameを決める
 </h1>
 <p>slotを学ぼう</p> 
 <h2>
  <slot name="catchCopy" /> // 置き換えたい部分のslot nameを決める
 </h2>
</div>

<style scoped>
.itemTitle {
 margin: 10px;
}
h1 {
 color: rgb(65, 193, 222);
}
p {
 color: gray;
h2 {
 color: rgb(76, 212, 227);
}
</style>
```

```index.vue
index.vue // 親ページ
<ItemTitle>
 <template v-slot:title>
  Hello Vue.js! // slot name="title"を置き換える
 </template>
 <template v-slot:catchCopy>
  # slotって？メリットは？ // slot name="catchCopy"を置き換える
 </template>
</ItemTitle>
```


おめでとうございます！
これでVue.js、Nuxt.jsのslot、今日から使えますね！わーい！
次は更なる応用も記載していきます★