【Vue.js】slotについて初心者にもわかりやすく解説します。

Vue.js Web制作

【Vue.js】slotについて初心者にもわかりやすく解説します。

なやむくん
slotとは何でしょうか…。

なやむさん
コード例を見ながらslotの使い方を学びたい…。

などの疑問や悩みを解決してまいります。

Vue.jsにおけるslot機能はとても便利なものですが、初心者が最初に扱う場合ややこしくてこんがらがってしまうことも多いかと思います。

今回は初心者の方に向けて分かりやすいようにslotについて解説していきます。

slotとは

slotとは親コンポーネントから子コンポーネントにコンテンツを挿入することができる機能です。

親コンポーネントから子コンポーネントに値を渡すPropsに似ていますが、Propsはデータを、slotはコンテンツを挿入するという違いがあります。

みつた
実際に使ってみたほうが分かりやすいかと思いますので、次の項で実際に使用しているコード例を見ながらイメージしていきましょう。

slotを使ったコード例紹介

それでは実際にslotを簡単なコードで使用してみます。

親コンポーネントにApp.vue、子コンポーネントにSlotContent.vueを用意しました。

<script setup lang="ts">
import SlotContent from './components/SlotContent.vue';
</script>

<template>
    <SlotContent>
      <!-- slotタグ内に入るコンテンツ -->
      <div class="content">
        <h1>slotの使い方について</h1>
        <p>初心者の方にもわかりやすく解説します。</p>
      </div>
      <!-- /slotタグ内に入るコンテンツ -->
    </SlotContent>
</template>
<template>
  <p>↓親コンポーネントのコンテンツの内容がslotタグ内に入ります。↓</p>
  <slot></slot>
</template>

表示結果は以下のようになります。

表示結果

コンポーネントタグ内のHTMLコンテンツが挿入される

わかりやすくコメントも記述していますが、子コンポーネントのSlotContentタグ内に記述されているHTMLコンテンツ(contentクラス)が、子コンポーネントのslotタグ内に挿入されたことが分かるかと思います。

<!-- slotタグ内に入るコンテンツ -->
<div class="content">
  <h1>slotの使い方について</h1>
  <p>初心者の方にもわかりやすく解説します。</p>
</div>

上記のコードが、

<slot></slot>

slotタグ内に挿入されました。

複数箇所に表示させる場合

1か所だけではなく複数箇所にHTMLコンテンツを反映させることも可能です。

空のslotタグをテキストの上にもう1つ配置してみてください。

するとテキストの上にも同様のコンテンツが表示されたかと思います。

表示結果

デフォルト(フォールバックコンテンツ)の指定

先の解説では、SlotContentタグ内にあったHTMLコンテンツを子コンポーネントの空のslotタグ内に挿入することができましたが、slotタグ内に内容を記述すると、SlotContentタグ内のコンテンツが何もないとき(空タグのとき)にフォールバックコンテンツを指定することができます。

<template>
  <!-- デフォルトの内容が入ります -->
  <SlotContent />

  <SlotContent>
    <div class="content">
      <h1>slotの使い方について</h1>
      <p>初心者の方にもわかりやすく解説します。</p>
    </div>
  </SlotContent>
</template>
<template>
  <slot>デフォルトの値が表示されます。</slot>
</template>

このように、先程とは異なりslotタグ内にテキストを追加しました。

親コンポーネント側はSlotContentタグ内にコンテンツがないものを別に用意しました。

表示は以下のようになります。

表示結果

子コンポーネントのslotタグ内が空の場合は親コンポーネントのSlotContentタグ内のコンテンツが挿入され、逆にSlotContentタグ内にコンテンツがない場合は、子コンポーネントのslotタグ内で指定したテキストの内容が反映されます。

名前付きスロットの指定

親コンポーネントから子コンポーネントに複数のコンテンツをそれぞれ決められた箇所に挿入したいときは名前付きスロット機能を利用します。

以下がその例です。

<script setup lang="ts">
import SlotContent from "./components/SlotContent.vue";
</script>

<template>
  <SlotContent>
    <template v-slot:header>
      <!-- header スロットのためのコンテンツ -->
      <h2>ヘッダーのタイトルが入ります。</h2>
      <p>ヘッダーのテキストが入ります。</p>
    </template>
    <template v-slot:default>
      <!-- main スロットのためのコンテンツ -->
      <h2>メインのタイトルが入ります。</h2>
      <p>メインのテキストが入ります。</p>
    </template>
    <template v-slot:footer>
      <!-- footer スロットのためのコンテンツ -->
      <h2>フッターのタイトルが入ります。</h2>
      <p>フッターのテキストが入ります。</p>
    </template>
  </SlotContent>
</template>
<script setup lang="ts"></script>

<template>
  <div class="container">
    <header>
      <!-- ここに header コンテンツが必要 -->
    <slot name="header"></slot>
    </header>
    <main>
      <!-- ここに main コンテンツが必要 -->
      <slot></slot>
    </main>
    <footer>
      <!-- ここに footer コンテンツが必要 -->
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<style scoped>
header,main,footer {
  padding: 5px;
  text-align: center;
  box-sizing: border-box;
}
header {
  background-color: coral;
}
main {
  background-color: deepskyblue;
  margin: 10px 0;
}
footer {
  background-color: goldenrod;
}
</style>

このようにheadermainfooterを用意して、それぞれに指定した内容のスロットコンポーネントを挿入します。

結果は以下のようになります。

表示結果

このように各コンテンツを表示させたいエリアに表示させることができました。

みつた
分かりやすいように色分けしています。

それでは解説していきたいと思います。

まずヘッダーの内容をheaderタグの中に、メインのコンテンツをmainタグの中に、フッターの内容をfooterタグの中に入れるために、template内にv-slot:結び付けたいキーを指定します。

次に子コンポーネントで結び付けたいキーと同様の名前をslotタグ内にname属性で指定してあげます。

このようにすることで親コンポーネントでv-slotで指定したキーを、子コンポーネント側でname属性を指定することで挿入先を指定することができます。

なやむくん
これまでの説明で、headerfooterは分かるのですがmainタグ内のv-slotにはdefaultが指定されていますが、子コンポーネント側にはname属性がありませんよ・・・

name属性を持たないように見えるslotタグですが、実は指定なしだと暗黙的にdefaultというname属性を持っているという特徴があります。

v-slot側でdefaultを指定することで、指定のないslotタグに挿入されることになります。

v-slotの省略形

最後にv-slotの省略形についてご紹介します。

v-bind:bindv-on:click@clickのようにv-slotも省略形が用意されています。

先程のv-slot:headerを省略する場合は#headerとなります。

<template>
  <SlotContent>
    <template #header>
      <!-- header スロットのためのコンテンツ -->
      <h2>ヘッダーのタイトルが入ります。</h2>
      <p>ヘッダーのテキストが入ります。</p>
    </template>
    <template #default>
      <!-- main スロットのためのコンテンツ -->
      <h2>メインのタイトルが入ります。</h2>
      <p>メインのテキストが入ります。</p>
    </template>
    <template #footer>
      <!-- footer スロットのためのコンテンツ -->
      <h2>フッターのタイトルが入ります。</h2>
      <p>フッターのテキストが入ります。</p>
    </template>
  </SlotContent>
</template>
もえるくん
v-slotを省略する場合は「#」を使用するんだね!
  • この記事を書いた人
  • 最新記事

みつた

完全未経験&異業種から30歳の年でIT企業に転職。

Web系開発言語が好き。
どちらかというとバックエンドよりもフロントエンドが好き(現時点では…)

最近はサウナと観葉植物にハマっている。
野球が好きで一応投手。

-Vue.js, Web制作