Vue Scoped Slots – Pass Data from Child to Parent Templates (2025 Guide)
Introduction – What Are Scoped Slots in Vue?
Scoped slots in Vue.js allow child components to expose data to the parent through slots. Unlike regular slots, which only pass HTML content from parent to child, scoped slots pass both content and logic, enabling truly dynamic UIs.
In this guide, you’ll learn:
- What scoped slots are and how they differ from regular slots
- How to use the
v-slotdirective with slot props - Real-world examples and use cases
- Best practices and common pitfalls
What Is a Scoped Slot?
Scoped slots allow a child component to pass data (slot props) back to the parent component, which then uses that data to dynamically render content.
This enables customized rendering logic in the parent, even though the data is owned by the child.
Basic Scoped Slot Syntax
Child Component (ListRenderer.vue)
<template>
<ul>
<li v-for="item in items" :key="item.id">
<slot :item="item" />
</li>
</ul>
</template>
<script>
export default {
props: ['items']
}
</script>
Parent Usage
<ListRenderer :items="products">
<template v-slot:default="{ item }">
<strong>{{ item.name }}</strong> – ${{ item.price }}
</template>
</ListRenderer>
The parent receives each item as a scoped prop and renders it as needed.
Why Use Scoped Slots?
Child defines structure and data
Parent controls presentation and rendering logic
Great for reusable components like:
- List rendering
- Table layouts
- Dynamic dropdowns
Full Example – User Card Renderer
UserList.vue (Child)
<template>
<div>
<slot v-for="user in users" :user="user" :key="user.id" />
</div>
</template>
<script>
export default {
props: ['users']
}
</script>
Parent Usage
<UserList :users="userData">
<template v-slot:default="{ user }">
<div class="card">
<h3>{{ user.name }}</h3>
<p>Email: {{ user.email }}</p>
</div>
</template>
</UserList>
Parent uses the data (user) to render the layout it wants, keeping the logic flexible.
Shorthand & Naming Slots
You can name the slot and use #name shorthand:
<template #user="{ user }">
<p>{{ user.name }}</p>
</template>
In child:
<slot name="user" :user="userData" />
Use Case – Table Header Renderer
Scoped slots are ideal for custom table headers:
<DataTable> (Child)
<template>
<table>
<thead>
<tr>
<slot name="header" />
</tr>
</thead>
<tbody>
<tr v-for="row in data" :key="row.id">
<slot name="row" :row="row" />
</tr>
</tbody>
</table>
</template>
Parent:
<DataTable :data="items">
<template #header>
<th>Name</th><th>Price</th>
</template>
<template #row="{ row }">
<td>{{ row.name }}</td><td>{{ row.price }}</td>
</template>
</DataTable>
Common Mistakes to Avoid
| Mistake | Solution |
|---|---|
Forgetting v-slot syntax | Always bind with v-slot:name="{ data }" |
Not using :key in loops | Add :key="item.id" in v-for elements |
Mixing up props vs slots | Props pass data from parent → child; scoped slots pass data from child → parent |
Summary – Recap & Next Steps
Scoped slots make components more powerful by giving data control to the parent while keeping logic inside the child. This creates flexible, reusable layouts—ideal for advanced UIs.
Key Takeaways:
- Scoped slots allow child components to expose data to parent templates
- Use
v-slot:name="{ slotProps }"in the parent - Ideal for rendering lists, tables, and custom dropdowns
- Combine with default and named slots for dynamic interfaces
Real-World Relevance:
Scoped slots power dashboards, data tables, cards, dropdowns, modals, and reusable content renderers in large Vue apps.
FAQ Section
What is a scoped slot in Vue?
A slot that passes data (slot props) from the child component to the parent for dynamic rendering.
How do I access slot props?
Use the v-slot directive in the parent:
<template v-slot:default="{ item }">{{ item.name }}</template>
Can scoped slots and named slots be used together?
Yes. Each named slot can also be scoped by passing props:
<slot name="header" :data="someValue" />
What’s the difference between props and scoped slots?
Props send data down from parent to child. Scoped slots send data up from child to parent.
Do I need scoped slots in every component?
No. Use them only when the parent needs control over rendering using child data.
Share Now :
