Слоты в SvelteKit позволяют создавать компоненты с гибкой структурой, где часть содержимого может быть передана извне. Это ключевой инструмент для композиции UI, особенно при разработке библиотек компонентов, где один и тот же каркас может использоваться с разным контентом.
В Svelte слоты задаются через <slot> внутри
компонента:
<!-- Card.svelte -->
<div class="card">
<slot></slot>
</div>
Использование:
<Card>
<h2>Заголовок карточки</h2>
<p>Описание содержимого карточки.</p>
</Card>
В этом примере весь переданный контент будет вставлен внутрь
<div class="card">.
Именованные слоты позволяют вставлять контент в конкретные области компонента. Это особенно полезно, когда компонент имеет несколько зон с разной семантикой.
<!-- Modal.svelte -->
<div class="modal">
<header><slot name="header"></slot></header>
<main><slot></slot></main>
<footer><slot name="footer"></slot></footer>
</div>
Использование именованных слотов:
<Modal>
<h1 slot="header">Заголовок модального окна</h1>
<p>Основной контент окна.</p>
<button slot="footer">Закрыть</button>
</Modal>
Если контент для именованного слота не передан, можно задать контент по умолчанию:
<header><slot name="header">Стандартный заголовок</slot></header>
Слоты могут принимать данные из родительского компонента через slot props. Это позволяет создавать компоненты с динамическим содержимым, где внутренняя логика компонента управляет передаваемыми данными.
<!-- Dropdown.svelte -->
<script>
export let items = [];
</script>
<ul>
{#each items as item}
<li><slot {item}>{item.name}</slot></li>
{/each}
</ul>
Использование с доступом к slot props:
<Dropdown items="{[{name: 'One'}, {name: 'Two'}]}">
<span let:item>{item.name.toUpperCase()}</span>
</Dropdown>
Здесь let:item связывает локальную переменную с пропом
слота, предоставленным компонентом.
Композиция — это создание сложных компонентов из более простых. В SvelteKit это особенно важно при разработке UI библиотек, где повторное использование элементов критично.
Компоненты могут включать друг друга, используя слоты и пропсы для передачи данных:
<!-- Form.svelte -->
<form on:submit|preventDefault={handleSubmit}>
<slot></slot>
</form>
<script>
function handleSubmit() {
console.log("Форма отправлена");
}
</script>
<Form>
<input type="text" placeholder="Имя" />
<button type="submit">Отправить</button>
</Form>
Можно строить компоненты, комбинируя несколько вложенных элементов с именованными слотами:
<!-- PageLayout.svelte -->
<header><slot name="header"></slot></header>
<aside><slot name="sidebar"></slot></aside>
<main><slot></slot></main>
<footer><slot name="footer"></slot></footer>
Использование:
<PageLayout>
<nav slot="header">Навигация</nav>
<aside slot="sidebar">Меню</aside>
<p>Основной контент страницы</p>
<footer slot="footer">Футер</footer>
</PageLayout>
Такой подход позволяет создавать универсальные и повторно используемые макеты, где разные части UI могут быть заменены без изменения структуры компонента.
Слоты можно использовать динамически, например, менять содержимое в зависимости от состояния:
<Modal>
{#if user.isLoggedIn}
<p slot="header">Добро пожаловать, {user.name}</p>
{:else}
<p slot="header">Пожалуйста, войдите</p>
{/if}
</Modal>
Это позволяет библиотекам компонентов быть гибкими и адаптивными, предоставляя разработчику полный контроль над контентом и структурой.
Слоты и композиция — фундаментальные инструменты для построения UI в SvelteKit. Правильное их использование позволяет создавать гибкие, повторно используемые и легко расширяемые компоненты, которые упрощают разработку сложных интерфейсов и библиотек UI.
Сочетание именованных слотов, slot props и вложенной композиции создаёт мощный инструмент для построения современных интерфейсов с минимальным дублированием кода.