Default Slots
A default slot is created when no name attribute is assigned to a <slot> element. It serves as the primary content injection point.
Named Slots
Named slots are defined by adding a name property. This allows a component to have multiple distribution outlets for different content peices.
Basic Implemantation Example
Parent Component (App.vue)
<template>
<ContentWrapper>
<!-- Using a named slot -->
<h2 slot="header">{{ pageTitle }}</h2>
<!-- Content for the default slot -->
<p>Main content goes here</p>
</ContentWrapper>
</template>
<script>
import ContentWrapper from './components/ContentWrapper.vue'
export default {
components: { ContentWrapper },
data() {
return {
pageTitle: 'Dashboard'
}
}
}
</script>
Child Component (ContentWrapper.vue)
<template>
<div class="container">
<header>
<slot name="header">Default Header</slot>
</header>
<main>
<slot>Fallback content if nothing is provided</slot>
</main>
</div>
</template>
Scoped Slots
Scoped slots allow child componants to pass data back up to the parent rendering the slot. This is useful for customizing the layout of list items or complex data structures.
Parent Component (App.vue)
<template>
<TaskList :items="taskList">
<template v-slot:default="slotProps">
<div :style="{ opacity: slotProps.item.completed ? 0.5 : 1 }">
Task #{{ slotProps.index + 1 }}: {{ slotProps.item.text }}
</div>
</template>
</TaskList>
</template>
<script>
import TaskList from './components/TaskList.vue'
export default {
components: { TaskList },
data() {
return {
taskList: [
{ id: 'a1', text: 'Learn Vue', completed: true },
{ id: 'b2', text: 'Build App', completed: false },
{ id: 'c3', text: 'Deploy', completed: false }
]
}
}
}
</script>
Child Component (TaskList.vue)
<template>
<ul>
<li v-for="(item, idx) in items" :key="item.id">
<!-- Attributes bound here are available in the parent scope -->
<slot :item="item" :index="idx"></slot>
</li>
</ul>
</template>
<script>
export default {
props: {
items: {
type: Array,
required: true
}
}
}
</script>