Named Slots
The panel has one place for content. The menu needs cards with three places: a heading at the top, the price in the middle and a button at the bottom, each in its own part of the card, with lines between them. A component can have several slots when it gives them names. Here's MenuCard.vue:
<template>
<article class="card">
<header>
<slot name="header" />
</header>
<div class="body">
<slot />
</div>
<footer>
<slot name="footer" />
</footer>
</article>
</template>A <slot> without a name is the default slot. The parent fills a named slot with a <template> that has # and the slot's name:
<MenuCard>
<template #header>
<h2>Carrot Cake</h2>
</template>
<p>€4</p>
<template #footer>
<button>Add</button>
</template>
</MenuCard>The <template> elements themselves aren't on the page, only their content: the heading goes into the card's header, and the button into its footer. The paragraph isn't in any <template #…>, so it goes into the default slot. The order in the parent doesn't matter: the card's template decides where each part goes.
#header is short for v-slot:header, as @click is short for v-on:click. You'll see both in other code; this course uses #. And the default slot is named default, so its content can also be in a <template #default>.
Why a slot for the heading, when the panel had a prop title? A prop is enough for a short text. Here, the heading also has a label with the category next to the name, and another card could have a picture there. A rule of thumb: data and short texts go into props, pieces of the page into slots. A component can have both, as the panel does.
Typical mistakes:
- Content for a named slot that isn't in a
<template #…>. It goes into the default slot, so it shows in the middle of the card. - A different name in the card and in the parent, such as
<slot name="footer" />and<template #foot>. A named slot that nothing fills stays empty, and content for a slot that the card doesn't have isn't shown, both without a warning. #on an element other than<template>, such as<button #footer>. That's a mistake in the file, and the red bar under the preview says where it is andv-slot can only be used on components or <template> tags.
Instructions
- 1
In
MenuCard.vue, put a slot namedheaderinto theheaderelement. InApp.vue, put each card's heading into<template #header>. - 2
Do the same for the button: a slot named
footerin the card'sfooter, and the button in<template #footer>.