Слот - місце в шаблоні компонента, куди батько вставляє свою розмітку. Компонент задає рамку, а вміст вирішує той, хто його використовує.
<!-- Card.vue -->
<div class="card">
<header><slot name="title" /></header>
<slot /> <!-- слот за замовчуванням -->
</div>
<Card>
<template #title>Замовлення №42</template>
<p>Деталі замовлення...</p>
</Card>
Scoped slot - слот, у який компонент передає дані назад батькові. Компонент знає дані, а батько - як їх показати.
<!-- DataTable.vue -->
<tr v-for="row in rows" :key="row.id">
<slot name="row" :row="row" :selected="selectedId === row.id" />
</tr>
<DataTable :rows="orders">
<template #row="{ row, selected }">
<td :class="{ 'font-bold': selected }">{{ row.number }}</td>
<td>{{ formatMoney(row.total) }}</td>
</template>
</DataTable>
Навіщо: таблиці, списки, випадаючі меню й інші компоненти з логікою (сортування, вибір, пагінація), але без жорстко заданого вигляду. Це той самий патерн, що render props у React.
Корисне:
$slots.title(чиuseSlots()) дозволяє перевірити, чи передали слот, і не рендерити порожню обгортку.- Вміст слота компілюється в області батька: він бачить змінні батька, а дані дитини - лише ті, що передані через scoped slot.