Slots provide a powerful way to compose components and inject content.
Default Slots
Pass unnamed content into a child component:
<template>
<Card>
<p>This is a default slot</p>
</Card>
</template>
<!-- Card.vue -->
<template>
<div class="card">
<slot />
</div>
</template>
Named Slots
Pass content into specific slots:
<template>
<Card>
<template #header>
<h1>Header Content</h1>
</template>
<p>Main Content</p>
</Card>
</template>
<!-- Card.vue -->
<template>
<div class="card">
<header><slot name="header" /></header>
<div><slot /></div>
</div>
</template>
Scoped Slots
Pass data from child to parent via slots:
<!-- Parent.vue -->
<template>
<List :items="items">
<template #default="{ item }">
<p>{{ item.name }}</p>
</template>
</List>
</template>
<script>
export default { data: () => ({ items: [{ name: 'Item 1' }, { name: 'Item 2' }] }) };
</script>
<!-- List.vue -->
<template>
<ul>
<li v-for="item in items" :key="item.id">
<slot :item="item" />
</li>
</ul>
</template>
<script>
export default { props: ['items'] };
</script>