Eine Komponente mit einem Slot
Auf der Seite des Cafés gibt es mehrere Kästen, die gleich aussehen: ein weißer Kasten mit Rahmen und einer Überschrift, und darin jedes Mal etwas anderes. Die Öffnungszeiten sind ein Absatz, die Speisekarte eine Liste, und die Bestellung eine Liste mit einem Button. Eine Komponente für den Kasten wäre praktisch, aber Props passen hier nicht. Eine Prop trägt einen Wert, etwa einen Text oder ein Objekt, und dieser Kasten muss ein Stück der Seite tragen.
Dafür hat eine Komponente einen Slot: eine Stelle in ihrer Vorlage, die ihr Elternteil füllt. Hier ist Panel.vue, ein Kasten mit einer Überschrift aus seiner Prop titel und einem Slot unter der Überschrift:
<script setup>
defineProps({
titel: { type: String, required: true },
});
</script>
<template>
<section class="panel">
<h2>{{ titel }}</h2>
<slot />
</section>
</template>Der Elternteil schreibt die Komponente mit einem öffnenden und einem schließenden Tag und setzt den Inhalt dazwischen, wie bei einem HTML-Element:
<Panel titel="Öffnungszeiten">
<p>Jeden Tag von 7 bis 19 Uhr.</p>
</Panel>Vue zeigt die Vorlage des Panels, mit dem Inhalt anstelle von <slot />. Die Seite bekommt:
<section class="panel">
<h2>Öffnungszeiten</h2>
<p>Jeden Tag von 7 bis 19 Uhr.</p>
</section>Der Inhalt kann alles sein, was du in eine Vorlage schreiben würdest: Text, mehrere Elemente, eine Liste mit v-for, sogar andere Komponenten. Und jedes Mal, wenn du das Panel verwendest, kannst du ihm anderen Inhalt geben.
Bisher hatten deine Komponenten nichts zwischen ihren Tags, deshalb hast du sie selbstschließend geschrieben, als <MenueEintrag />. Und eine Komponente ohne <slot /> tut mit dem Inhalt zwischen ihren Tags nichts: Vue lässt ihn weg, ohne Warnung. Erscheint Inhalt nicht, prüfe zuerst, ob die Komponente einen Slot hat.
So schreibst du es:
Anweisungen
- 1
Setze in
Panel.vue<slot />unter die Überschrift, sodass das Panel mit den Öffnungszeiten seinen Absatz zeigt. - 2
Füge in
App.vueunter dem ersten ein zweites Panel hinzu, mit dem TitelKuchen des Tagesund dem AbsatzKarottenkuchen mit Walnüssen, 4 €.