Vue.js スロット(Slots)
スロット(Slots)は Vue における強力な機能であり、コンポーネントの柔軟性と再利用性を高めるために利用されます。
Vue のスロットを使用すると、親コンポーネントから子コンポーネントの <template> 内にコンテンツを送り込むことができます。
1. スロットの基本
これまでの学習では、<template> 内でコンポーネントを呼び出す際、次のような自己完結型のタグとして使用してきました。
App.vue:
<template>
<slot-comp />
</template>しかし、スロットを利用すれば、開始タグと終了タグを使用し、その間にテキストなどのコンテンツを挿入することができます。
App.vue:
<template>
<slot-comp>Hello World!(ハロー・ワールド)</slot-comp>
</template>この「Hello World!」を子コンポーネント側で受け取り、ページに表示させるには、コンポーネント内で <slot> タグを使用する必要があります。<slot> タグはコンテンツのプレースホルダとして機能し、アプリケーションがビルドされた後、<slot> は送られてきたコンテンツに置き換わります。
1.1 実装例
SlotComp.vue:
<template>
<div>
<p>SlotComp.vue(子コンポーネント)</p>
<slot></slot>
</div>
</template>2. スロットをカードとして活用する
スロットは、動的な HTML コンテンツの大きな塊をラップして、カード(Card)のような外観を作るためにも使用できます。
以前はコンポーネント内のコンテンツを作成するために props でデータを送っていましたが、スロットを使えば HTML コンテンツをそのまま直接 <slot> タグに送り込むことが可能です。
2.1 実装例
App.vue:
<template>
<h3>Vue におけるスロット</h3>
<p>foods 配列からカード形式の div ボックスを作成します。</p>
<div id="wrapper">
<slot-comp v-for="x in foods" :key="x.name">
<img v-bind:src="x.url">
<h4>{{x.name}}</h4>
<p>{{x.desc}}</p>
</slot-comp>
</div>
</template>コンテンツが <slot> のあるコンポーネントに入ると、その <slot> を div で囲み、その div に対してローカルにスタイルを適用します。これにより、アプリケーション内の他の div に影響を与えることなく、コンテンツの周囲にカードのような外観を作成できます。
SlotComp.vue:
<template>
<div> <slot></slot>
</div>
</template>
<script></script>
<style scoped>
div {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
border-radius: 10px;
margin: 10px;
padding: 10px;
}
</style>コンテンツの周囲にカード型のフレームを生成するコンポーネントは、異なる要素に対しても同じフレームを使い回すことで再利用できます。
次の例では、食べ物のアイテムに使ったものと同じコンポーネントを使用して、フッターを作成しています。
App.vue:
<template>
<h3>再利用可能なスロットカード</h3>
<p>foods 配列からカード形式の div ボックスを作成します。</p>
<p>また、同じコンポーネントを再利用してカード形式のフッターも作成します。</p>
<div id="wrapper">
<slot-comp v-for="x in foods" :key="x.name">
<img v-bind:src="x.url">
<h4>{{x.name}}</h4>
</slot-comp>
</div>
<footer>
<slot-comp>
<h4>フッター内容</h4>
</slot-comp>
</footer>
</template>3. フォールバックコンテンツ(Fallback Content)
コンポーネントがコンテンツなしで呼び出された場合に備えて、<slot> 内にフォールバックコンテンツ(代替コンテンツ)を設定しておくことができます。
3.1 実装例
このアプリケーションの最初のコンポーネントにはコンテンツが渡されていないため、フォールバックコンテンツがレンダリングされます。
App.vue:
<template>
<h3>スロットのフォールバックコンテンツ</h3>
<p>コンテンツが提供されないコンポーネントでは、slot タグ内のフォールバックコンテンツが表示されます。</p>
<slot-comp>
</slot-comp>
<slot-comp>
<h4>このコンテンツは App.vue から提供されています</h4>
</slot-comp>
</template>SlotComp.vue:
<template>
<div>
<slot>
<h4>これはフォールバックコンテンツ(デフォルト)です</h4>
</slot>
</div>
</template>