LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 1817 min read

Slots

Pass template content into a child component using default, named, and scoped slots.

The Default Slot

A <slot> element inside a component's template marks a spot where the parent can inject its own markup — not just a data value, but actual HTML/components.

<!-- AppCard.vue -->
<template>
<div class="card">
<slot />
</div>
</template>
<!-- Parent -->
<template>
<AppCard>
<h3>Product Name</h3>
<p>Product description goes here.</p>
</AppCard>
</template>

Fallback Content

Content placed between the <slot> tags renders only if the parent doesn't provide anything for that slot — a useful default.

<template>
<button class="app-button">
<slot>Submit</slot> <!-- shown if the parent passes nothing -->
</button>
</template>

Named Slots

A component can define multiple slots by giving each a name, letting the parent target specific regions of the child's layout.

<!-- AppLayout.vue -->
<template>
<header><slot name="header" /></header>
<main><slot /></main>
<footer><slot name="footer" /></footer>
</template>
<!-- Parent -->
<template>
<AppLayout>
<template #header>
<h1>My Site</h1>
</template>
<p>Main page content goes in the default slot.</p>
<template #footer>
<p>&copy; 2026</p>
</template>
</AppLayout>
</template>
The # Shorthand

#header is shorthand for v-slot:header — you'll see the shorthand in almost all real-world Vue templates.

Scoped Slots

A scoped slot lets the child pass data back up into the slot content the parent provides — useful when the child owns a list, but the parent wants control over how each item renders.

<!-- ProductList.vue -->
<template>
<ul>
<li v-for="product in products" :key="product.id">
<slot :product="product" />
</li>
</ul>
</template>
<!-- Parent — decides exactly how each product renders -->
<template>
<ProductList :products="products">
<template #default="{ product }">
<strong>{{ product.name }}</strong> — {{ product.price }}
</template>
</ProductList>
</template>

Common Beginner Mistakes

Reaching for props when you actually need a slot

If the parent needs to pass arbitrary markup or components (not just data values), a slot is the right tool — a prop can only carry data, not template structure.

Forgetting the # shorthand syntax on <template>

Named and scoped slot content must be wrapped in a <template #slotName> tag — putting it directly as a child without that wrapper sends it to the default slot instead.

FAQs

Yes — as shown in the AppLayout example, the unnamed slot content becomes the default slot, alongside explicitly named ones.

The default slot is conceptually similar to React's children prop; named and scoped slots go further, letting you target multiple insertion points and pass data back to the parent's markup.

Summary

Slots let a parent inject markup into specific places inside a child's template, with scoped slots even letting the child hand data back for that markup to use. Next, you'll look at rendering components dynamically.

Next Lesson →

Dynamic & Async Components