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.
Default slots
Section titled “Default slots”The simplest slot is the default slot. Use <slot /> in the child to mark where the parent’s content appears:
<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.
Fallback content
Section titled “Fallback content”If the parent passes nothing, <slot> renders its default content:
<template> <div class="card"> <slot>No content provided.</slot> </div></template>Named slots
Section titled “Named slots”When a component needs multiple injection points, use named slots:
<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.
When to use slots vs props
Section titled “When to use slots vs props”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.
Exercise
Section titled “Exercise”- Create
src/components/RelationshipSection.vuewith a namedheaderslot and a default slot. - The
headerslot should be wrapped in a styled<h2>. - The default slot should be wrapped in a
flex-wrapdiv. - 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.