0
0
Vueframework~5 mins

Named slots and scoped slots in Vue

Choose your learning style9 modes available
Introduction

Named slots let you put different content in specific places inside a component. Scoped slots let the component share data with the content you put inside it.

You want to create a reusable card component with separate header, body, and footer areas.
You need to pass data from a list component to customize how each item looks.
You want to build a modal where the title and buttons can be different each time.
You want to let users customize parts of a component but still keep control over layout.
Syntax
Vue
<template>
  <slot name="slotName">Default content</slot>
</template>

<!-- Using named slot -->
<ChildComponent>
  <template #slotName>
    Custom content here
  </template>
</ChildComponent>

<!-- Scoped slot syntax -->
<ChildComponent>
  <template #slotName="slotProps">
    {{ slotProps.someData }}
  </template>
</ChildComponent>

Named slots use the name attribute to identify different slots.

Scoped slots pass data from the child component to the parent using slot props.

Examples
This component has three slots: named slots for header and footer, and a default slot for the main content.
Vue
<!-- ChildComponent.vue -->
<template>
  <header><slot name="header">Default Header</slot></header>
  <main><slot>Default Body</slot></main>
  <footer><slot name="footer">Default Footer</slot></footer>
</template>
Here, we fill the named slots with custom content and use the default slot for the main body.
Vue
<!-- Using ChildComponent with named slots -->
<ChildComponent>
  <template #header>
    <h1>My Custom Header</h1>
  </template>
  <p>This is the main body content.</p>
  <template #footer>
    <small>Custom footer text</small>
  </template>
</ChildComponent>
The child component passes itemText to the slot as a prop named text.
Vue
<!-- ChildComponent.vue with scoped slot -->
<template>
  <slot name="item" :text="itemText"></slot>
</template>

<script setup>
const itemText = 'Hello from child'
</script>
The parent receives the text from the child and displays it inside the slot content.
Vue
<!-- Using scoped slot -->
<ChildComponent>
  <template #item="{ text }">
    <p>Received: {{ text }}</p>
  </template>
</ChildComponent>
Sample Program

This example shows a card component with named slots for header and footer. The parent fills these slots with custom content and uses the default slot for the main body.

Vue
<!-- Card.vue -->
<template>
  <div class="card">
    <header class="card-header">
      <slot name="header">Default Header</slot>
    </header>
    <section class="card-body">
      <slot>Default Body Content</slot>
    </section>
    <footer class="card-footer">
      <slot name="footer">Default Footer</slot>
    </footer>
  </div>
</template>

<style scoped>
.card { border: 1px solid #ccc; padding: 1rem; border-radius: 0.5rem; max-width: 300px; }
.card-header, .card-footer { background: #f0f0f0; padding: 0.5rem; }
.card-body { padding: 1rem 0; }
</style>


<!-- App.vue -->
<template>
  <Card>
    <template #header>
      <h2>Welcome!</h2>
    </template>

    <p>This is the main card content.</p>

    <template #footer>
      <button @click="alert('Clicked!')">Click me</button>
    </template>
  </Card>
</template>

<script setup>
import Card from './Card.vue'
</script>
OutputSuccess
Important Notes

Always provide default slot content to keep your component usable without custom slots.

Use v-bind or : to pass multiple props in scoped slots.

Named slots help organize complex components with multiple customizable parts.

Summary

Named slots let you put different content in specific places inside a component.

Scoped slots let the child component share data with the slot content.

Use named and scoped slots to build flexible, reusable Vue components.