【Vue】Vue.jsでアボカドチーズバーガーを作ってみることにした(<slot>の使い方ハンズオン)

## はじめに
今日はハンバーガーを食べたので、ついでにVue.jsのコンポーネントの機能のひとつ**`<slot>`**の基本的な使い方についてまとめました。

Vue.jsで**アボカドチーズバーガー**を作っていきましょう:relaxed:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/76af536b-2670-6e73-dd4b-e7182610f439.png)
## 環境
```yaml
OS: macOS Catalina 10.15.1
Vue: 2.6.10
```
## 1.バンズを用意し、皿に乗せる
最近はレタスで肉を挟んだハンバーガーもありますが、やっぱり**バンズ**でしょう。

まずは**バンズ**を用意します。
※`Bun.vue`

```vue:Bun.vue
<template>
  <div>
    <div class="bun bun-top">バンズ（上）</div>
    <div class="bun bun-bottom">バンズ（下）</div>
  </div>
</template>

<style>
  .bun {
    width: 200px;
    height: 50px;
    background: brown;
  }
  .bun-top {
    border-radius: 40px 40px 0 0;
  }
  .bun-bottom {
    border-radius: 0 0 20px 20px;
  }
</style>
```

テーブルに直に置くわけにはいきません。
**お皿**も用意し、とりあえず**バンズだけ**載せましょう。
※`Dish.vue`

```vue:Dish.vue
<template>
  <div>
    <Bun></Bun>
    <div class="dish"></div>
  </div>
</template>

<script>
  import Bun from './humburger/Bun'

  export default {
    components: {
      Bun,
    }
  }
</script>

<style>
  .dish {
    width: 200px;
    height: 10px;
    border-radius: 5px;
    background: grey;
  }
</style>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/ae7ccce4-2547-850e-f431-c474305a65b4.png)


現状、こうなります。

**またお腹がすいてきました。**
どんどんいきましょう！

## 2.切れ込みを入れる(`slot`を仕込む)
切れ込み(`<slot>`)を入れます。

```vue:Bun.vue
<template>
  <div>
    <div class="bun bun-top">バンズ（上）</div>
    <slot></slot>
    <div class="bun bun-bottom">バンズ（下）</div>
  </div>
</template>
...
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/925e7f3b-9442-b99f-dce5-e76ddf556eed.png)


現状はこうなります。

**ポイント**は、まだ見た目に変化はないということです。

そう、**ただの切れ込み**なので**具材がなくても**、別に違和感なく食すことができます。

さて、次は具材です。

## 3.パティ（ビーフ100%）を用意する
まずは**パティ（肉）**がないといけませんね。
仕込みましょう。

```vue:BeefPatty.vue
<template>
  <div class="beef">パティ（ビーフ100%）</div>
</template>

<style>
  .beef {
    width: 200px;
    height: 30px;
    background: rgb(72, 19, 19);
    border-radius: 5px;
  }
</style>
```

そして、ついに**バンズに挟む**ときが！
※`<slot>`の活用

```vue:Dish.vue
<template>
  <div>
    <Bun>
      <BeefPatty></BeefPatty>
    </Bun>
    <div class="dish"></div>
  </div>
</template>

<script>
  import Bun from './humburger/Bun'
  import BeefPatty from './humburger/BeefPatty'

  export default {
    components: {
      Bun,
      BeefPatty,
    }
  }
</script>
...
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/4d6987de-168a-5663-db1b-f6f68d4bcf94.png)

結果はこうなります。

事前に**切れ込みを入れていた**ので、このようにして**具材を挟み込む**ことが出来ます。

さあ、**パティ**だけでは寂しいので他の具材も仕込んで挟みましょう！

## 4.その他の具材を用意する
確か...食べた**アボカドチーズバーガー**に入っていた具材は残り3種類。

- アボカド
- トマト
- チーズ

```vue:Avocato.vue
<template>
  <div class="avocado">アボカド</div>
</template>

<style>
  .avocado {
    width: 200px;
    height: 20px;
    background: greenyellow;
    border-radius: 10px;
  }
</style>
```

```vue:Tomato.vue
<template>
  <div class="tomato">トマト</div>
</template>

<style>
  .tomato {
    width: 200px;
    height: 40px;
    background: red;
    border-radius: 5px;
  }
</style>
```

```vue:Cheese.vue
<template>
  <div class="cheese">チーズ</div>
</template>

<style>
  .cheese {
    width: 200px;
    height: 20px;
    background: yellow;
    border-radius: 10px;
  }
</style>
```

具材を挟みます。

```vue:Dish.vue
<template>
  <div>
    <Bun>
      <Avocado></Avocado>
      <Tomato></Tomato>
      <Cheese></Cheese>
      <BeefPatty></BeefPatty>
    </Bun>
    <div class="dish"></div>
  </div>
</template>

<script>
  import Bun from './humburger/Bun'
  import BeefPatty from './humburger/BeefPatty'
  import Avocado from './humburger/Avocado'
  import Tomato from './humburger/Tomato'
  import Cheese from './humburger/Cheese'

  export default {
    components: {
      Bun,
      BeefPatty,
      Avocado,
      Tomato,
      Cheese,
    }
  }
</script>
...
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/76af536b-2670-6e73-dd4b-e7182610f439.png)

結果はこうなります。
彩り豊かで美味しそうです！

このように、**切れ込みを入れてある**ので、**いくつでも具材が挟み込めます**。

これでも十分なのですが、もしかすると**これではお腹が満たされない**という人もいるかもしれません。

次は、**もう一つ切れ込み**を入れてみましょう。

## 5.もう一つ切れ込みを入れる(更に`slot`を仕込む)

```vue:Bun.vue
<template>
  <div>
    <div class="bun bun-top">バンズ（上）</div>
    <slot></slot>
    <div class="bun bun-middle">バンズ（中）</div>
    <slot></slot>
    <div class="bun bun-bottom">バンズ（下）</div>
  </div>
</template>

<style>
...
  .bun-middle {
    height: 30px;
  }
...
</style>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/598a8764-8877-daf1-d88f-7ff24949f9b4.png)
結果はこうなります。
**...ボリューミィ！**

`slot`が２つになったので、それぞれの`slot`に**同じ具材**が挟まれてしまいました。

これではやりすぎなので、それぞれの`slot`に対して名前をつけて、挟む具材を指定出来るようにしましょう。

## 6.切れ込み毎に具材を変える（名前付き`slot`）

```vue:Bun.vue
<template>
  <div>
    <div class="bun bun-top">バンズ（上）</div>
    <slot name="upper"></slot>
    <div class="bun bun-middle">バンズ（中）</div>
    <slot name="lower"></slot>
    <div class="bun bun-bottom">バンズ（下）</div>
  </div>
</template>
...
```

- 上側の切れ込み：`upper`
- 下側の切れ込み：`lower`

という名前をつけてあげました。

これでそれぞれ挟む具材を変更できます。
※名前なしの場合、`default`という名前がついています。

では、具材を挟んでいきましょう！

```vue:Dish.vue
<template>
  <div>
    <Bun>
      <template v-slot:upper>
        <Avocado></Avocado>
        <Tomato></Tomato>
        <Cheese></Cheese>
        <BeefPatty></BeefPatty>
      </template>
      <template v-slot:lower>
        <Cheese></Cheese>
        <BeefPatty></BeefPatty>
      </template>
    </Bun>
    <div class="dish"></div>
  </div>
</template>
...
```

ここで挟む場所を明記するため、`template`タグに`v-slot:スロット名`としてあげて、中身を囲ってあげます。

※ここで、`v-slot:default`とすると、名前無しスロットに紐づきます。

これでOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/d45df3b9-74b5-2a81-ec8c-c9e531f4c34a.png)

結果はこちら。
いい感じですね！

**以上です！**

あとはお好みで**具材**を変えたり**10段バーガー**にしたりしてお楽しみ下さい:yum:

## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
- [スロット — Vue.js](https://jp.vuejs.org/v2/guide/components-slots.html)