Slots
Slots ermöglichen es, Template-Inhalte in Komponenten einzufügen.
Default Slot
Abschnitt betitelt „Default Slot“<template> <div class="card"> <slot></slot> <!-- Platzhalter für Inhalt --> </div></template><!-- Verwendung --><template> <BaseCard> <h2>Titel</h2> <p>Beliebiger Inhalt hier...</p> </BaseCard></template>Fallback Content
Abschnitt betitelt „Fallback Content“<template> <button type="submit"> <slot> Submit <!-- Wird gezeigt wenn kein Inhalt übergeben --> </slot> </button></template><!-- Verwendung --><template> <SubmitButton /> <!-- Zeigt "Submit" --> <SubmitButton>Speichern</SubmitButton> <!-- Zeigt "Speichern" --></template>Named Slots
Abschnitt betitelt „Named Slots“<template> <div class="card"> <header> <slot name="header"></slot> </header> <main> <slot></slot> <!-- Default Slot --> </main> <footer> <slot name="footer"></slot> </footer> </div></template><!-- Verwendung --><template> <BaseCard> <template #header> <h2>Kartenheader</h2> </template>
<p>Hauptinhalt (default slot)</p>
<template #footer> <button>Aktion</button> </template> </BaseCard></template>Conditional Slots
Abschnitt betitelt „Conditional Slots“<template> <div class="card"> <header v-if="$slots.header"> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer v-if="$slots.footer"> <slot name="footer"></slot> </footer> </div></template>Scoped Slots
Abschnitt betitelt „Scoped Slots“Daten von der Kind-Komponente an den Slot-Inhalt übergeben:
<script setup>defineProps(['items'])</script>
<template> <ul> <li v-for="item in items" :key="item.id"> <slot :item="item" :index="index"> {{ item.name }} <!-- Fallback --> </slot> </li> </ul></template><!-- Verwendung --><template> <ItemList :items="todos"> <template #default="{ item, index }"> <span>{{ index + 1 }}. {{ item.name }}</span> <button @click="remove(item.id)">X</button> </template> </ItemList></template>Named Scoped Slots
Abschnitt betitelt „Named Scoped Slots“<template> <table> <thead> <tr> <th v-for="col in columns" :key="col.key"> <slot :name="`header-${col.key}`" :column="col"> {{ col.label }} </slot> </th> </tr> </thead> <tbody> <tr v-for="row in data" :key="row.id"> <td v-for="col in columns" :key="col.key"> <slot :name="`cell-${col.key}`" :row="row" :value="row[col.key]"> {{ row[col.key] }} </slot> </td> </tr> </tbody> </table></template><!-- Verwendung --><template> <DataTable :columns="columns" :data="users"> <template #cell-status="{ value }"> <span :class="value">{{ value }}</span> </template> <template #cell-actions="{ row }"> <button @click="edit(row)">Edit</button> </template> </DataTable></template>Renderless Components
Abschnitt betitelt „Renderless Components“Komponenten, die nur Logik bereitstellen:
<script setup>import { ref, onMounted, onUnmounted } from 'vue'
const x = ref(0)const y = ref(0)
function update(e) { x.value = e.pageX y.value = e.pageY}
onMounted(() => window.addEventListener('mousemove', update))onUnmounted(() => window.removeEventListener('mousemove', update))</script>
<template> <slot :x="x" :y="y"></slot></template><!-- Verwendung --><template> <MouseTracker v-slot="{ x, y }"> <p>Mouse: {{ x }} / {{ y }}</p> </MouseTracker></template>Dokumentation
Abschnitt betitelt „Dokumentation“Offizielle Vue Dokumentation:
- Slots - Content Distribution
- Scoped Slots