Lesson 9 / 25
Slots
Letting the parent supply content.
Default, named and scoped slots
Props pass data; slots pass template content. A child places <slot /> where the parent's content should appear, with optional fallback content inside. Named slots (<slot name="header" />) let a component expose several areas, filled with <template #header>. Scoped slots pass data back up to the slot content: the child writes <slot :item="item" /> and the parent receives it with <template #default="{ item }">. This is how list, table and layout components let callers control rendering while the component controls behaviour.
A card and a list with a scoped slot
Named slots and slot props.
<!-- BaseCard.vue -->
<template>
<section class="card">
<header><slot name="header">Untitled</slot></header>
<slot />
</section>
</template>
<!-- ItemList.vue -->
<script setup>
defineProps({ items: { type: Array, required: true } })
</script>
<template>
<ul>
<li v-for="item in items" :key="item.id">
<slot :item="item">{{ item.name }}</slot>
</li>
</ul>
</template>
<!-- Parent template -->
<!--
<BaseCard>
<template #header>Products</template>
<ItemList :items="products">
<template #default="{ item }">
<strong>{{ item.name }}</strong> - {{ item.price }}
</template>
</ItemList>
</BaseCard>
-->A picture frame
A component with slots is a frame: it decides the border and layout, and the parent decides which picture goes inside.
Quick check: What do scoped slots add compared with ordinary slots?
- They limit slots to one per component
- They apply scoped CSS to the slot
- The child can pass data to the slot content provided by the parent
- They render slot content on the server only
Answer
The child can pass data to the slot content provided by the parent — Slot props flow from child to parent template.