【Nuxt.js】Nuxt文法編：v-slot(初級)

# slotとは

テキストの置き換えができるものです！
子コンポーネントにslotを置いて
親で自由に置き換えます✍️

テキスト以外を置き換えたい場合は
propsを使います
https://note.com/aliz/n/n99144d4556b9


使う場所が多かったり
デザインが凝っていて
いちいちコピペすると
コードが長くなってしまう場合に有効です💕
そもそもコンポーネント化するほどでもない
なんてこともあるので使い所は考えましょう💡

# slotによる置き換え

【作るもの】
エラー表示のテキストを作ります。
色やError!の文字は使いまわしたいので、
後ろの文章のみを親で置き換えます🍒

<img width="620" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/b6b83e57-e38e-c59e-4d4d-c85015b1e1f0.png">

**【ディレクトリ 】**
コンポーネントは
アトミックデザインに基づいて作成しています！

**❓アトミックデザイン**
　要素の大きさごとにファイルを分けます🙋‍♀️
　コンポーネントがどこにあるのか
　分かりやすくなります💕
　大きさの分類はここが参考になります！
　Atomic Designとは

```bash:file
components/
--| atom/
----| texts/
-----| TextError.vue

pages/
--| index.vue
--| sample.vue
```

**【解説/TextError】**
**・slotタグ部分**
　今回はpタグを親で自由に変更したいので
　pタグの中にslotを入れます。
　親で任意のテキストを使わない場合は
　子で記載しているLABELがそのまま表示されます。

```TextError.vue
<template>
 <div class="text text-error">
   <strong>Error!</strong>
   <p><slot>LABEL</slot></p>
 </div>
</template>

<script>
export default {
}
</script>

<style lang="scss" scoped>
 .text-error {
   display: inline-block;
   padding: 4px 8px;
   background-color: #f3beb8;
   border: 1px solid #f09898;
 }
</style>
```

```index.vue
<template>
 <div class="page">
   <TextError>
     // ここに任意のテキスト
     画面遷移時に問題が発生しました！
   </TextError>
 </div>
</template>

<script>
import TextError from '~/components/atom/texts/TextError.vue'

export default {
 components: {
   TextError,
 },
}
</script>
```

別のページで他のテキストを表示させたい場合も
簡単に表示できますね💃✨

```sample.vue
<template>
 <div class="page">
   <TextError>
     ただいまサイトが大変混雑しています！
   </TextError>
 </div>
</template>

<script>
import TextError from '~/components/atom/texts/TextError.vue'

export default {
 components: {
   TextError,
 },
}
</script>
```

【表示】
<img width="620" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/bc91268b-8b64-3b56-198f-4c7fa838df74.png">


ちなみに、
親でdataを使って
表示させることも可能です🍀

```sample.vue
<template>
 <div class="page">
   <TextError>
     {{ text }}
   </TextError>
 </div>
</template>

<script>
import TextError from '~/components/atom/texts/TextError.vue'

export default {
 components: {
   TextError,
 },
 data () {
  return {
   text: 'ただいまサイトが大変混雑しています！',
  }
 },
}
</script>
```

# 名前付きスロット

**【作るもの】**
ページタイトルとサブタイトル
それぞれを親で任意のテキストに
変更できるようにしたいです！
slotが2つ必要ですね💡
![picture_pc_9a9709d27b26e8526a7abd8cd10c9ef5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/5d239e88-4ec7-3a8c-d5c1-4f9991477951.png)

```bash:file
components/
--| atom/
----| titles/
-----| TitlePage.vue

pages/
--| index.vue
```

**【解説/TitlePage.vue】
・slot name**
　slotを複数使う場合は
　それぞれにnameをつけます👦👧

```TitlePage.vue
<template>
 <div class="title title-page">
   <h2 class="title">
     <slot name="title">
       Title
     </slot>
   </h2>
   <p class="sub-title">
     <slot name="subtitle">
       Sub Title
     </slot>
   </p>
 </div>
</template>

<script>
export default {
}
</script>

<style lang="scss" scoped>
 .title-page {
   text-align: center;

   > .title {
     color: #E92323;
   }

   > .sub-title {
     color: #F9C8C8;
   }
 }
</style>
```

**【解説/index.vue】
・template v-slot:title**
　名前付きslotを使う時には
　templateタグが必要になります！
　v-slot:{slotの名前}で
　名前付きslotを指定します。

```index.vue
<template>
 <div class="page">
   <TitlePage>
     <template v-slot:title>
       Create!
     </template>
     <template v-slot:subtitle>
       Create your account
     </template>
   </TitlePage>
 </div>
</template>

<script>
import TitlePage from '~/components/atom/titles/TitlePage.vue'

export default {
 components: {
   TitlePage,
 },
}
</script>
```

💡v-slot:は#で省略できます

💡nameをつけなかったslotは
　defaultという名前を持ちます
　
💡h2, pタグは親で指定することも可能ですが
　共通したタグを
　使用することがほとんどです。
　子で書いた方が統一感があるため
　これはどうしても、という時に使いましょう！

# 次回予告

【Nuxt.js】firebase基礎編(Auth版)：アカウント作成をできるようにしよう
6/19(金)公開です🌟
**記事が公開したときにわかる様
フォローをお願いします😀💕**
https://twitter.com/aLizlab