Формы и инпуты

SvelteKit предоставляет мощный и декларативный подход к созданию форм, упрощая управление состоянием инпутов, валидацию и отправку данных. Формы в SvelteKit строятся на стандартных HTML-элементах (<form>, <input>, <textarea>, <select>) с добавлением реактивности через связывание данных (bind:value) и обработку событий.


Двустороннее связывание данных

Ключевой особенностью Svelte является bind:value, позволяющий синхронизировать состояние инпута и переменной в компоненте:

<script>
  let username = '';
  let password = '';
</script>

<form on:submit|preventDefault={handleSubmit}>
  <input type="text" placeholder="Имя пользователя" bind:value={username} />
  <input type="password" placeholder="Пароль" bind:value={password} />
  <button type="submit">Войти</button>
</form>

<script>
  function handleSubmit() {
    console.log({ username, password });
  }
</script>
  • bind:value={variable} автоматически обновляет переменную при изменении значения инпута.
  • Использование модификатора |preventDefault на событии submit предотвращает перезагрузку страницы.

Работа с различными типами инпутов

SvelteKit поддерживает все стандартные типы инпутов, при этом двустороннее связывание работает и с чекбоксами, и с радио-кнопками.

Чекбоксы:

<script>
  let subscribe = false;
</script>

<label>
  <input type="checkbox" bind:checked={subscribe} />
  Подписка на новости
</label>
  • Для чекбоксов используется bind:checked вместо bind:value.

Радиокнопки:

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

<label>
  <input type="radio" name="gender" value="male" bind:group={gender} />
  Мужской
</label>
<label>
  <input type="radio" name="gender" value="female" bind:group={gender} />
  Женский
</label>
  • bind:group синхронизирует выбранное значение радио-группы с переменной.

Текстовые поля и textarea

<input type="text"> и <textarea> полностью совместимы с реактивными переменными:

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

<textarea bind:value={comment} placeholder="Оставьте комментарий"></textarea>
<p>Количество символов: {comment.length}</p>
  • Динамическое отображение количества символов или предварительная обработка текста возможны без дополнительного состояния.

Селекты и множественный выбор

Для <select> доступна реактивная привязка через bind:value и bind:group для множественного выбора:

<script>
  let country = '';
  let languages = [];
</script>

<sel ect bind:value={country}>
  <option value="">Выберите страну</option>
  <option value="ru">Россия</option>
  <option value="us">США</option>
</select>

<sel ect multiple bind:value={languages}>
  <option value="en">Английский</option>
  <option value="ru">Русский</option>
  <option value="fr">Французский</option>
</select>
  • multiple позволяет выбирать несколько значений одновременно.
  • Результат привязан к массиву переменной.

Валидация и реактивные ошибки

SvelteKit упрощает реактивную валидацию форм через $: и вычисляемые значения:

<script>
  let email = '';
  let password = '';
  $: emailError = email.includes('@') ? '' : 'Введите корректный email';
  $: passwordError = password.length >= 6 ? '' : 'Пароль должен быть не менее 6 символов';
</script>

<form on:submit|preventDefault={handleSubmit}>
  <input type="email" placeholder="Email" bind:value={email} />
  {#if emailError}<span class="error">{emailError}</span>{/if}

  <input type="password" placeholder="Пароль" bind:value={password} />
  {#if passwordError}<span class="error">{passwordError}</span>{/if}

  <button type="submit" disabled={emailError || passwordError}>Регистрация</button>
</form>
  • Ошибки автоматически обновляются при изменении значений.
  • Кнопка отправки может быть заблокирована, если есть ошибки.

Асинхронная обработка форм

Для работы с сервером можно использовать actions SvelteKit:

<form method="POST" use:enhance>
  <input type="text" name="username" bind:value={username} />
  <button type="submit">Отправить</button>
</form>

<script>
  import { enhance } fr om '$app/forms';

  let username = '';

  function handleFormSubmit({ result, form }) {
    console.log('Данные формы:', form);
    console.log('Ответ сервера:', result);
  }
</script>
  • enhance позволяет обрабатывать формы асинхронно без перезагрузки страницы.
  • Данные формы автоматически сериализуются и отправляются на серверную обработку.

Компонентные UI-библиотеки для SvelteKit

Для более сложных интерфейсов форм можно использовать специализированные библиотеки:

  • Svelte Material UI (SMUI) — набор компонентов Material Design с полной интеграцией форм.
  • SvelteStrap — Bootstrap-стиль компоненты с поддержкой bind:value.
  • Carbon Components Svelte — корпоративные UI-компоненты с расширенной валидацией и доступностью.

Примеры использования:

<script>
  import TextField fr om '@smui/textfield';
  let name = '';
</script>

<TextField bind:value={name} label="Имя" required outlined />
  • Такие компоненты поддерживают все базовые свойства инпутов, плюс дополнительные стили и визуальные эффекты.
  • Реактивность и двустороннее связывание сохраняются.

Управление состоянием форм

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

<script>
  let formData = {
    name: '',
    email: '',
    password: ''
  };
</script>

<input type="text" bind:value={formData.name} placeholder="Имя" />
<input type="email" bind:value={formData.email} placeholder="Email" />
<input type="password" bind:value={formData.password} placeholder="Пароль" />
  • Позволяет централизованно хранить все данные формы.
  • Удобно для отправки на сервер и динамической валидации.

Динамические поля формы

SvelteKit позволяет создавать поля на лету с помощью реактивных массивов:

<script>
  let tasks = [''];
  function addTask() {
    tasks = [...tasks, ''];
  }
</script>

{#each tasks as task, index}
  <input type="text" bind:value={tasks[index]} placeholder="Задача {index + 1}" />
{/each}

<button type="button" on:click={addTask}>Добавить задачу</button>
  • Каждый инпут синхронизирован с соответствующим элементом массива.
  • Простое управление динамическими наборами данных без потери реактивности.

Итоговый подход

Формы в SvelteKit объединяют чистый HTML, реактивность Svelte, и современные UI-библиотеки, обеспечивая:

  • Простое связывание значений инпутов
  • Реактивную валидацию
  • Асинхронную отправку данных
  • Интеграцию с компонентными библиотеками
  • Динамическое управление полями

Такой подход делает работу с формами максимально гибкой, модульной и удобной для любых веб-приложений.