Vue

Lesson 10

Slots for component composition

Use slots when a reusable Vue shell needs caller-owned content, actions, or layout regions.

Good Code

PanelShell.vue
<script setup lang="ts">
defineProps<{ labelledBy: string }>();

// Slots let callers supply content without adding mode flags.
</script>

<template>
  <section class="panel" :aria-labelledby="labelledBy">
    <header>
      <slot name="title" />
    </header>
    <div class="panel__body">
      <slot />
    </div>
    <footer>
      <slot name="actions" />
    </footer>
  </section>
</template>

Bad Code

PanelShell.vue
<script setup>
defineProps(["title", "body", "showApprove", "showArchive", "showCancel"]);

// Boolean flags force the shell to know every caller action.
</script>

<template>
  <section class="panel">
    <h2>{{ title }}</h2>
    <p>{{ body }}</p>
    <button v-if="showApprove">Approve</button>
    <button v-if="showArchive">Archive</button>
    <button v-if="showCancel">Cancel</button>
  </section>
</template>

Review Notes

What to review

Good Code

The good version owns the panel structure and lets the caller provide title, body, and actions through named slots.

Bad Code

The bad version adds one prop for every possible action. Each new caller can force the shell component to learn another special case.

Takeaways

  • Slots let the parent own variable content while the child owns shared structure and accessibility.