SvelteKit предоставляет удобный способ работы с формами и
input-элементами, сочетая реактивность Svelte с мощью современных
UI-библиотек. Основной подход заключается в связывании состояния формы с
переменными компонента через двустороннюю привязку
(bind:value). Это позволяет автоматически обновлять
значения input-полей при изменении состояния и наоборот.
<script>
let username = '';
let email = '';
</script>
<form on:submit|preventDefault={() => console.log({ username, email })}>
<label>
Имя пользователя:
<input type="text" bind:value={username} placeholder="Введите имя">
</label>
<label>
Email:
<input type="email" bind:value={email} placeholder="Введите email">
</label>
<button type="submit">Отправить</button>
</form>
Ключевые моменты:
bind:value обеспечивает реактивность без
необходимости вручную обновлять состояние.|preventDefault предотвращает стандартное
поведение отправки формы.actions SvelteKit.Валидация форм может выполняться на нескольких уровнях: встроенные
HTML-атрибуты (required, pattern,
minlength) и кастомная логика в скрипте компонента. Для
крупных форм лучше использовать отдельный объект состояния ошибок.
<script>
let username = '';
let email = '';
let errors = {};
function validate() {
errors = {};
if (!username) errors.username = 'Имя обязательно';
if (!email.includes('@')) errors.email = 'Неверный формат email';
return Object.keys(errors).length === 0;
}
function handleSubmit() {
if (validate()) {
console.log('Форма валидна:', { username, email });
}
}
</script>
<form on:submit|preventDefault={handleSubmit}>
<label>
Имя пользователя:
<input type="text" bind:value={username}>
{#if errors.username}<span class="error">{errors.username}</span>{/if}
</label>
<label>
Email:
<input type="email" bind:value={email}>
{#if errors.email}<span class="error">{errors.email}</span>{/if}
</label>
<button type="submit">Отправить</button>
</form>
Особенности подхода:
errors позволяет
динамически показывать ошибки рядом с полями.Alert или
Tooltip.SvelteKit UI-библиотеки, такие как Svelte Material UI (SMUI) или SvelteStrap, предоставляют готовые компоненты input, checkbox, radio и sel ect с расширенными возможностями стилизации и валидации.
Пример использования SMUI TextField:
<script>
import TextField fr om '@smui/textfield';
let password = '';
</script>
<TextField
bind:value={password}
type="password"
label="Пароль"
outlined
required
/>
Преимущества кастомных компонентов:
bind:value работает без дополнительного кода).disabled, error,
helperText).Checkbox и radio-кнопки также легко интегрируются с состоянием
компонента. Для checkbox часто используют булевы значения, а для radio —
один общий bind:group.
<script>
let acceptTerms = false;
let gender = '';
</script>
<label>
<input type="checkbox" bind:checked={acceptTerms}>
Согласен с условиями
</label>
<label>
<input type="radio" bind:group={gender} value="male"> Мужской
</label>
<label>
<input type="radio" bind:group={gender} value="female"> Женский
</label>
Важные нюансы:
bind:checked, а не
bind:value.bind:group,
что обеспечивает корректное поведение выбора.Для select-элементов применяются стандартные HTML-теги
<select> или компоненты UI-библиотек, поддерживающие
мультивыбор. Динамическое создание опций через массив данных делает код
более универсальным.
<script>
let selectedCountry = '';
const countries = ['Россия', 'США', 'Германия'];
</script>
<select bind:value={selectedCountry}>
<option value="">Выберите страну</option>
{#each countries as country}
<option value={country}>{country}</option>
{/each}
</select>
Для multi-select, например в SMUI:
<script>
import Select fr om '@smui/select';
let selectedFruits = [];
const fruits = ['Яблоко', 'Банан', 'Груша'];
</script>
<Select bind:value={selectedFruits} multiple>
{#each fruits as fruit}
<option value={fruit}>{fruit}</option>
{/each}
</Select>
Особенности:
multiple позволяет сохранять несколько
значений в массив.SvelteKit Actions позволяют обрабатывать отправку форм на сервере без
перезагрузки страницы. Input-значения передаются через
formData, а результаты можно возвращать в компонент для
отображения ошибок или успешной отправки.
<script context="module">
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const username = data.get('username');
if (!username) return { errors: { username: 'Имя обязательно' } };
return { success: true };
}
};
</script>
<form method="POST" use:enhance>
<input name="username" type="text">
<button type="submit">Отправить</button>
</form>
Преимущества подхода:
В сложных приложениях состояние формы часто организуют через объект
form, где каждый ключ соответствует полю. Это упрощает
работу с динамическими формами и компонентами UI-библиотек.
<script>
let form = {
username: '',
email: '',
password: ''
};
</script>
<input type="text" bind:value={form.username} placeholder="Имя">
<input type="email" bind:value={form.email} placeholder="Email">
<input type="password" bind:value={form.password} placeholder="Пароль">
Преимущества: