Структура компонентов

В SvelteKit компоненты являются ключевым строительным блоком приложения. Каждый компонент — это отдельный файл с расширением .svelte, который может содержать разметку HTML, стили CSS и скрипты JavaScript/TypeScript. Структура компонентов строится вокруг трёх основных секций:

  1. Скриптовая секция <script> Здесь объявляются переменные, функции, импорты других компонентов и библиотек. Переменные, экспортируемые с помощью export let, становятся свойствами (props) компонента:

    <script>
      export let title = 'Заголовок';
      let counter = 0;
    
      function increment() {
        counter += 1;
      }
    </script>
  2. Секция разметки HTML Отвечает за визуальное представление компонента. Разметка может содержать динамические выражения, связывание данных (bind:), события (on:) и условные блоки ({#if ...}):

    <h1>{title}</h1>
    <button on:click={increment}>
      Нажато {counter} раз
    </button>
    {#if counter > 5}
      <p>Вы превысили пять нажатий!</p>
    {/if}
  3. Секция стилей <style> Встроенные стили применяются только к текущему компоненту. Использование :global() позволяет создавать глобальные правила:

    <style>
      h1 {
        color: #2c3e50;
      }
    
      :global(body) {
        margin: 0;
        font-family: sans-serif;
      }
    </style>

Вложенные и повторно используемые компоненты

SvelteKit поощряет композицию компонентов, когда один компонент импортирует и использует другие. Это позволяет создавать модульную архитектуру:

<script>
  import Button from './Button.svelte';
</script>

<div class="card">
  <h2>Карточка</h2>
  <Button label="Нажми меня"/>
</div>

Ключевые аспекты:

  • Props передаются сверху вниз через export let.
  • События можно передавать вверх через createEventDispatcher.
  • Компоненты можно динамически рендерить с помощью {#each} и условных блоков {#if}.

Связывание данных и реактивность

Одним из сильных инструментов SvelteKit является реактивность переменных. Реактивные выражения объявляются с помощью $::

<script>
  let a = 2;
  let b = 3;
  $: sum = a + b; // sum автоматически обновляется при изменении a или b
</script>

<p>Сумма: {sum}</p>

Также возможно двустороннее связывание с элементами формы:

<script>
  let name = '';
</script>

<input bind:value={name} placeholder="Введите имя"/>
<p>Привет, {name}!</p>

Управление состоянием через сторы

Для глобального состояния SvelteKit использует store. Основные типы:

  1. Writable store – изменяемое состояние:

    import { writable } from 'svelte/store';
    export const counter = writable(0);
  2. Readable store – только для чтения, часто используется для данных из API.

  3. Derived store – вычисляемое состояние на основе других сторов.

Подключение к компоненту происходит через $storeName:

<script>
  import { counter } from './stores.js';
</script>

<button on:click={() => counter.update(n => n + 1)}>
  Нажато {$counter} раз
</button>

Слоты и композиция интерфейсов

Слоты позволяют компонентам быть контейнерами для произвольного контента:

<!-- Modal.svelte -->
<div class="modal">
  <slot></slot>
</div>

<!-- App.svelte -->
<Modal>
  <h2>Заголовок модального окна</h2>
  <p>Содержимое внутри модалки</p>
</Modal>
  • Поддерживаются именованные слоты: <slot name="header">.
  • Можно комбинировать с условной логикой для динамических интерфейсов.

Структура проекта и организация компонентов

В SvelteKit часто придерживаются следующей схемы каталогов:

src/
 ├─ lib/
 │   ├─ components/
 │   │   ├─ Button.svelte
 │   │   ├─ Card.svelte
 │   │   └─ Modal.svelte
 │   ├─ stores/
 │   │   └─ counter.js
 │   └─ utils/
 ├─ routes/
 │   └─ index.svelte
  • lib/components — переиспользуемые UI-компоненты.
  • lib/stores — глобальные состояния.
  • routes — страницы приложения, где компоненты используются для построения интерфейса.
  • Такой подход облегчает масштабирование и поддержку кода, особенно в крупных приложениях.

Обработка событий и кастомные события

Для передачи событий из дочернего компонента вверх используется createEventDispatcher:

<script>
  import { createEventDispatcher } from 'svelte';
  const dispatch = createEventDispatcher();

  function notify() {
    dispatch('message', { text: 'Привет из компонента!' });
  }
</script>

<button on:click={notify}>Отправить сообщение</button>

На родительском компоненте:

<ChildComponent on:message={(e) => console.log(e.detail.text)} />

Поддержка TypeScript

SvelteKit полностью поддерживает TypeScript в компонентах:

<script lang="ts">
  export let count: number;
  function increment(): void {
    count += 1;
  }
</script>
  • Типизация props и функций повышает безопасность кода.
  • Легко интегрируется с store и сторонними библиотеками.

Использование библиотек UI с SvelteKit

Популярные UI-библиотеки (например, Svelte Material UI, Flowbite Svelte, Skeleton) предоставляют готовые компоненты, которые легко интегрируются с архитектурой компонентов:

  • Импорт компонентов напрямую в .svelte файлы.
  • Использование props для конфигурации внешнего вида и поведения.
  • Поддержка слотов и событий для полной кастомизации.

Пример использования компонента Button из Svelte Material UI:

<script>
  import Button from 'svelte-material-ui/Button';
</script>

<Button raised on:click={() => alert('Нажато!')}>
  Кнопка Material
</Button>
  • Можно комбинировать с локальными компонентами для построения сложных интерфейсов.
  • Структурирование компонентов по принципу “молекула → организм → страница” позволяет создавать чистую и масштабируемую архитектуру.

Резюме по структуре компонентов

  • Каждый компонент состоит из скрипта, разметки и стилей.
  • Используются props, слоты, события и сторы для связи между компонентами.
  • Слоты обеспечивают гибкую композицию интерфейсов.
  • Структура проекта (lib/components, routes) обеспечивает модульность и переиспользуемость.
  • Реактивность $: и двустороннее связывание упрощают управление состоянием локально.
  • Интеграция с UI-библиотеками позволяет ускорить разработку интерфейсов без потери архитектурной чистоты.

Эта структура формирует основу для надежных, легко поддерживаемых и расширяемых приложений на SvelteKit.