Good Code
The good version owns the panel structure and lets the caller provide title, body, and actions through named slots.
Lesson 10
Use slots when a reusable Vue shell needs caller-owned content, actions, or layout regions.
<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><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>The good version owns the panel structure and lets the caller provide title, body, and actions through named slots.
The bad version adds one prop for every possible action. Each new caller can force the shell component to learn another special case.