Skip to content

Slots

Props pass data to a component. Slots pass HTML content. They let a parent inject markup into a specific place in a child component’s template — making components far more flexible.

The simplest slot is the default slot. Use <slot /> in the child to mark where the parent’s content appears:

Card.vue
<template>
<div class="card">
<slot />
</div>
</template>

The parent wraps content between the component’s opening and closing tags:

<Card>
<h2>Alice Smith</h2>
<p>Born 1982</p>
</Card>

Vue places <h2>Alice Smith</h2><p>Born 1982</p> inside the .card div. The Card component handles styling; the parent controls the content.

If the parent passes nothing, <slot> renders its default content:

<template>
<div class="card">
<slot>No content provided.</slot>
</div>
</template>

When a component needs multiple injection points, use named slots:

SectionCard.vue
<template>
<div class="section-card">
<header class="section-header">
<slot name="header" />
</header>
<div class="section-body">
<slot />
</div>
</div>
</template>

The parent targets named slots with <template #slotname>:

<SectionCard>
<template #header>
<h2>Biological Parents</h2>
</template>
<PersonCard name="Alice" />
<PersonCard name="Bob" />
</SectionCard>

Content without a <template #name> goes to the default slot. Content with <template #header> goes to the header slot.

Use props when the parent passes data (strings, numbers, objects).
Use slots when the parent passes HTML structure or other components.

A PersonCard that shows a name takes props — the parent shouldn’t control the HTML structure of the card. A generic Card container that can wrap anything takes slots — the parent should control the content.

  1. Create src/components/RelationshipSection.vue with a named header slot and a default slot.
  2. The header slot should be wrapped in a styled <h2>.
  3. The default slot should be wrapped in a flex-wrap div.
  4. In App.vue, use <RelationshipSection> to render a “Parents” section containing two <PersonCard> instances.
  • <slot /> marks where a parent’s content appears in the child’s template.
  • Fallback content inside <slot> renders when the parent provides nothing.
  • Named slots (<slot name="header" />) let a component have multiple injection points.
  • The parent targets named slots with <template #slotname>.
  • Use props for data, slots for HTML content.