31. Slots и именованные слоты
Слоты — это механизм передачи контента в компонент снаружи. Аналог children в React, но значительно мощнее: Astro поддерживает именованные слоты, фолбэки и проверку наличия контента.
Дефолтный слот
Заголовок раздела «Дефолтный слот»Самый простой случай — компонент, который оборачивает любой контент:
<div class="card"> <slot /></div>---import Card from './Card.astro';---
<Card> <p>Этот текст попадёт в слот</p></Card>Именованные слоты
Заголовок раздела «Именованные слоты»Если нужно несколько мест для контента, используйте именованные слоты:
<article class="blog-card"> <header> <slot name="header" /> </header> <div class="body"> <slot /> </div> <footer> <slot name="footer" /> </footer></article><BlogCard> <h2 slot="header">Заголовок статьи</h2> <p>Основной текст статьи...</p> <button slot="footer">Читать далее</button></BlogCard>Фолбэк-контент
Заголовок раздела «Фолбэк-контент»Если слот не заполнен — отображается фолбэк:
<div class="card"> <slot name="header"> <!-- Показывается, если header не передан --> <h3>Заголовок по умолчанию</h3> </slot> <slot> <p>Контент не предоставлен</p> </slot></div>Проверка наличия слота: Astro.slots.has()
Заголовок раздела «Проверка наличия слота: Astro.slots.has()»Иногда нужно изменить структуру в зависимости от того, заполнен ли слот:
---const hasFooter = Astro.slots.has('footer');const hasSidebar = Astro.slots.has('sidebar');---
<div class:list={['layout', { 'with-sidebar': hasSidebar }]}> <main> <slot /> </main> {hasSidebar && ( <aside> <slot name="sidebar" /> </aside> )} {hasFooter && ( <footer> <slot name="footer" /> </footer> )}</div>Рендеринг слота в переменную
Заголовок раздела «Рендеринг слота в переменную»Можно получить HTML слота как строку:
---const headerContent = await Astro.slots.render('header');---
<div data-has-header={!!headerContent}> <Fragment set:html={headerContent} /></div>Передача пропсов в слот
Заголовок раздела «Передача пропсов в слот»Astro поддерживает передачу данных из компонента в переданный контент:
---const items = ['apple', 'banana', 'cherry'];---
<ul> {items.map((item) => ( <slot name="item" item={item} /> ))}</ul>Паттерн Layout со слотами
Заголовок раздела «Паттерн Layout со слотами»Самое распространённое применение — лейаут-компоненты:
---const { title } = Astro.props;---<!DOCTYPE html><html> <head> <title>{title}</title> <slot name="head" /> </head> <body> <slot name="header"> <header>Шапка по умолчанию</header> </slot> <main> <slot /> </main> <slot name="footer"> <footer>Подвал по умолчанию</footer> </slot> </body></html>Slots vs Props
Заголовок раздела «Slots vs Props»Используйте слоты, когда передаёте:
- HTML/компоненты (разметку)
- Контент, который может меняться на каждой странице
- Большие блоки текста
Используйте props, когда передаёте:
- Примитивные значения (строки, числа, булевы)
- Данные для вычислений внутри компонента
- Конфигурацию поведения