Vue.js
Beginner
1 min read
Slots: Default, Named, and Scoped
Example
<!-- BaseCard.vue — exposes three named slots -->
<template>
<div class="card">
<header v-if="$slots.header" class="card__header">
<slot name="header" />
</header>
<main class="card__body">
<slot /><!-- default slot -->
</main>
<footer v-if="$slots.footer" class="card__footer">
<!-- scoped slot: pass data back to parent -->
<slot name="footer" :closeCard="close" />
</footer>
</div>
</template>
<script setup>
const emit = defineEmits(['close']);
const close = () => emit('close');
</script>
<!-- Parent usage -->
<template>
<BaseCard @close="show = false">
<template #header>
<h2>Card Title</h2>
</template>
<p>Main body content goes here via the default slot.</p>
<!-- Destructure scoped slot data -->
<template #footer="{ closeCard }">
<button @click="closeCard">Dismiss</button>
</template>
</BaseCard>
</template>