Vue.jsのスロットを理解する！

## プロジェクトの作成

今回はvue cliををつかっていきます。

```
vue create プロジェクト名
```

App.vue を書き換えていきます。

```App.vue
<template>
<div>
  <h1>スロットを学んでいきます</h1>
  <hr>
  <Test name="阿部" message="よろしくお願いいたします。"></Test>
</div>
</template>

<script>
import Test from "../src/components/Test"
export default {
  components: {
    Test,
  }
}
</script>

<style>
hr {
  border: 1px solid red;
}
</style>
```

コンポーネントを一つ作成します。

```src/components/Test.vue
<template>
  <div>
    <h1>名前は{{name}}です</h1>
    <p>{{message}}</p>
  </div>
</template>

<script>
export default {
  props: {
    name: {
      type: String,
      required: true,
    },
    message: {
      type: String,
      required: true,
    },
  },
}
</script>
```
![スクリーンショット 2021-03-22 18.08.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/7073df26-7cbb-9e36-683b-3362df6071be.png)

現在は純粋にpropsを受け取っている状態になります。


## スロットとは？
親から子にデータを渡す際にHTMLのタグのデータまで同時に渡すことができます。
実際にやってみた方が早そうなのでやってみます

```App.vue
 <Test name="阿部" message="よろしくお願いいたします。">
    <hr>
    <h1>こちらスロットです</h1>
 </Test>
```
App.vueの部分を書き換えてみましょう

```Test.vue
<template>
  <div>
    <h1>名前は{{name}}です</h1>
    <p>{{message}}</p>
    <slot></slot>
  </div>
</template>
```
Testコンポーネント部分にslotタグを設置します。
![スクリーンショット 2021-03-22 18.12.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/07d4608e-1339-5580-c28d-163ddee5ce8b.png)

こうなります。
つまり親の　<Test>コンポーネントの間に記述したHTMLの内容がslotで受け取れているのがわかると思います。

```App.vue
<template>
<div>
  <h1>スロットを学んでいきます</h1>
  <hr>
  <Test name="阿部" message="よろしくお願いいたします。">
    <hr>
    <h1>{{slotMessage}}</h1>
  </Test>
</div>
</template>

<script>
import Test from "../src/components/Test"
export default {
  components: {
    Test,
  },
  data() {
    return {
      slotMessage: "スロットのメッセージです"
    }
  }
}
</script>
 ```
このようにデータプロパティを追加して子にデータを渡すことも可能になります。

## デフォルトのスロット
```
<slot>デフォルトのスロット</slot>
```
スロットはスロットタグの中にデフォルトのスロットを設定することができます。
これはコンポーネント内のデータがない場合のみ、デフォルトのスロットが適用され、ある場合はデフォルトのスロットは打ち消されます。

## 名前つきスロット
```
<slot></slot>
<slot></slot>
<slot></slot>
```
複数スロットっておけるの？
結論から言うとできます。

![スクリーンショット 2021-03-22 18.22.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/afcbedb4-fc75-7f71-fcf7-c239be489282.png)
純粋に3つおくとスロットが3つ描画されます。

ではこのスロットをそれぞれ違う文字を描画していきたい場合、使うのが名前付きスロットです！

App.vueを書き換えましょう

```App.vue
<template>
<div>
  <h1>スロットを学んでいきます</h1>
  <hr>
  <Test name="阿部" message="よろしくお願いいたします。">
    <hr>
    <template v-slot:first>        
      <p>一つ目のスロット</p>
    </template>
    <template v-slot:second>        
      <p>二つ目のスロット</p>
    </template>
    <template v-slot:third>        
      <p>三つ目のスロット</p>
    </template>
  </Test>
</div>
</template>

<script>
import Test from "../src/components/Test"
export default {
  components: {
    Test,
  },
}
</script>

<style>
hr {
  border: 1px solid red;
}
</style>
```

```Test.vue
<template>
  <div>
    <h1>名前は{{name}}です</h1>
    <p>{{message}}</p>
    <slot name="first"></slot>
    <slot name="second"></slot>
    <slot name="third"></slot>
  </div>
</template>

<script>
export default {
  props: {
    name: {
      type: String,
      required: true,
    },
    message: {
      type: String,
      required: true,
    },
  },
}
</script>
```

説明するとまずまずtemplateタグで囲みv-slotディレクティブを設定します(こちらは好きな値を追加しましょう)
受け取る側はname属性で指定した値を受け取ります。
これで言うと

```
//これで送信
<template v-slot:first>
最初のスロット
</template>

//これで受け取り
<template name="first">
```
ってイメージです！
ここは必ずtemplateタグを使う必要がありv-slotとtemplateはセットだと思ってください。
ちなみにこの名前付きスロットはバージョン2.6.0以上で対応しています！

## 省略記法
v-slotは#に省略することができます。

```
v-slot:title  ===  #title
```
って感じです。

お疲れさまでした！！