■ はじめに
Vue.jsを学習中のエンジニアです👩🏻💻
Vue.jsの<slot>
について学習した際、インプットの段階では理解できていると思っていたものの、実際にアウトプットしようとすると使い方が分からなくなってしまいました。この経験を踏まえて、自分自身の理解度の確認に加え、同じように困っている方の助けになればと思い、このトピックを取り上げました!
■ Slotとは
Slotは、親コンポーネントから子コンポーネントにコンテンツを挿入する仕組みです。これにより、子コンポーネントが親から受け取ったコンテンツを特定の場所に表示することができます。
具体的な使い方は、親コンポーネント内で子コンポーネントを使用し、子コンポーネント内にSlotを配置します。これにより、親コンポーネントで子コンポーネントのタグ内に挿入したコンテンツが、Slotに渡されます。そして、子コンポーネント内で受け取ったコンテンツを特定の場所に表示します。
言葉だけでの説明だとわかりづらいと思うので、以下では実際のコードを使用して、lotの使い方について説明します。
■ Slotの使い方
例えば、親コンポーネントで子コンポーネントを使用し、その中にテキストを挿入する場合、以下のような形になります。
<script setup>
import ChildComponent from './ChildComponent.vue';
</script>
<template>
<div>
<h1>親コンポーネント</h1>
<ChildComponent>
<p>子コンポーネントへのコンテンツ</p>
</ChildComponent>
</div>
</template>
<template>
<div>
<h2>子コンポーネント</h2>
<div>
<slot />
</div>
</div>
</template>
それぞれのファイルをブラウザで実行すると、次のような表示になります。
親コンポーネント
子コンポーネントへのコンテンツ
子コンポーネント
子コンポーネントへのコンテンツ
■ PropsとSlotの違い
-
Props(プロパティ)の特徴
- 親コンポーネントが子コンポーネントにデータを直接指定することが可能
- 子コンポーネントでは受け取ったデータを変更することができない
- HTML要素そのものを渡すことができない
-
Props(プロパティ)の使い方
<script setup>
import ChildComponent from './ChildComponent.vue';
const parentMessage = 'Hello from parent!';
</script>
<template>
<ChildComponent :message="parentMessage" />
</template>
<script setup>
const props = defineProps({
message: String
});
</script>
<template>
<div>{{ props.message }}</div>
</template>
先ほどProps(プロパティ)の特徴の中で、
HTML要素そのものを渡すことができないと記載しましたが、実際にどういうことなのか具体例を用いて説明します。
例)
① 親コンポーネントでmessageという変数を用意します。
const message = ref("<p>Hello world!</p>");
② 変数messageを次のようにProps経由で子コンポーネントに渡したとします。
<ChildComponent v-bind:message="message" />
③ 子コンポーネントで次のようにマスタッシュ構文で表示させようとした場合、エスケープされるため、HTML要素とは認識されず、文字列として表示されてしまいます。
<section>
{{ props.message }}
</section>
<p>Hello world!</p>
- Slot特徴
- 親コンポーネントから子コンポーネントに複数の要素を渡すことが可能
- コンポーネントの内部構造を調整し、再利用することが可能
- 動的なコンテンツをコンポーネントに挿入可能
※ Slotの使い方に関しては、■ Slotの使い方を参照してください。
■ Slotのオススメの使い分け
どんなときにSlotを使用するかわからないこともあると思うので、私が実際に先輩から教示いただいことを記載します。Slotを使用する場合は、以下の場合がオススメです✨
- 挿入したい内容に変更がない場合
- (挿入したい内容に変更がない)複数の要素挿入したい場合
- ディレクティブを追加で複数使用することがない場合
- 例)複数のディレクティブ使用
<button class="action-btn" :class="props.btnClass":disabled="isDisabled">
■ 最後に
ここまで記事を読んで下さり誠にありがとうございます!
インプットの際に理解できていると思っていても案外実務で使用するってなった場合に、あれ?どうやって使うんだっけ?思い通りの処理にならない。。みたいなことって結構あるなと思ったので、インプットしたことはQiitaの記事やコードをたくさん書いてアウトプットするべきだなと深く感じました!