Валидация данных является важной частью любого веб-приложения. В Svelte процесс валидации можно реализовать просто и эффективно, используя возможности реактивности фреймворка. Реализуя валидацию в реальном времени, можно повысить качество пользовательского взаимодействия, предупреждая ошибки до отправки формы.
Svelte позволяет легко отслеживать изменения данных и немедленно реагировать на них с помощью реактивных выражений и подписок. Реактивность фреймворка позволяет автоматически обновлять интерфейс при изменении значений, что идеально подходит для реализации валидации в реальном времени. Основная идея заключается в том, чтобы валидировать введённые пользователем данные по мере их ввода, предоставляя обратную связь без необходимости ожидать отправки формы.
Типичный компонент формы в Svelte включает в себя несколько ключевых элементов:
Пример простого компонента формы с валидацией:
<script>
let email = '';
let password = '';
let errors = {
email: '',
password: ''
};
$: emailValid = validateEmail(email);
$: passwordValid = validatePassword(password);
function validateEmail(value) {
if (!value) {
return 'Email обязателен';
}
const emailRegex = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
return emailRegex.test(value) ? '' : 'Неверный формат email';
}
function validatePassword(value) {
if (!value) {
return 'Пароль обязателен';
}
if (value.length < 6) {
return 'Пароль должен содержать хотя бы 6 символов';
}
return '';
}
</script>
<form>
<div>
<label for="email">Email:</label>
<input id="email" bind:value={email} type="email" />
{#if emailValid}
<p class="error">{emailValid}</p>
{/if}
</div>
<div>
<label for="password">Пароль:</label>
<input id="password" bind:value={password} type="password" />
{#if passwordValid}
<p class="error">{passwordValid}</p>
{/if}
</div>
<button type="submit" disabled={emailValid || passwordValid}>Отправить</button>
</form>
<style>
.error {
color: red;
font-size: 12px;
}
</style>
Реактивность в Svelte позволяет автоматически вычислять ошибку, когда
значение поля меняется. Выражение
$: emailValid = validateEmail(email) будет автоматически
пересчитываться каждый раз, когда меняется значение email.
Это позволяет поддерживать актуальные данные о статусе валидации без
необходимости вручную обновлять UI.
Иногда требуется проводить асинхронные проверки, например, проверку
уникальности email на сервере. Для этого можно использовать промисы и
async/await внутри реактивных выражений.
Однако Svelte не позволяет напрямую использовать асинхронные выражения в
реактивных вычислениях. Для этого можно создать отдельные методы или
подписки для асинхронной валидации.
Пример асинхронной валидации email:
<script>
let email = '';
let emailError = '';
let isEmailValid = false;
async function checkEmailAvailability(value) {
const response = await fetch(`/check-email?email=${value}`);
const result = await response.json();
return result.isAvailable ? '' : 'Этот email уже занят';
}
$: {
if (email) {
checkEmailAvailability(email).then(error => {
emailError = error;
isEmailValid = !error;
});
}
}
</script>
<form>
<div>
<label for="email">Email:</label>
<input id="email" bind:value={email} type="email" />
{#if emailError}
<p class="error">{emailError}</p>
{/if}
</div>
<button type="submit" disabled={!isEmailValid}>Отправить</button>
</form>
В данном примере асинхронная функция
checkEmailAvailability выполняет запрос на сервер и
возвращает строку с ошибкой, если email уже занят.
Для улучшения пользовательского опыта можно внедрить валидацию,
которая будет запускаться не только при каждом изменении, но и при
потере фокуса (событие blur). Это позволяет предоставлять
пользователю информацию о валидности данных без необходимости постоянно
вводить текст.
Пример использования события blur для проверки
email:
<script>
let email = '';
let emailError = '';
function handleBlur() {
emailError = validateEmail(email);
}
</script>
<form>
<div>
<label for="email">Email:</label>
<input id="email" bind:value={email} type="email" on:blur={handleBlur} />
{#if emailError}
<p class="error">{emailError}</p>
{/if}
</div>
<button type="submit" disabled={emailError}>Отправить</button>
</form>
Одной из ключевых задач при валидации является информирование
пользователя о том, что именно нужно исправить. Для этого можно
использовать текстовые подсказки и уведомления. В Svelte это можно
сделать с помощью условных блоков ({#if}), чтобы показывать
сообщения об ошибках в реальном времени.
Важной практикой является предоставление полезных, но лаконичных сообщений, чтобы не перегружать интерфейс.
Хотя Svelte предоставляет удобные средства для валидации, иногда возникает потребность в использовании более сложных решений, например, при реализации валидации на стороне клиента с учётом разных типов данных. Для этого можно использовать сторонние библиотеки, такие как Yup или VeeValidate.
Пример использования Yup для валидации формы:
<script>
import * as yup from 'yup';
let email = '';
let password = '';
let emailError = '';
let passwordError = '';
const schema = yup.object().shape({
email: yup.string().email('Неверный формат email').required('Email обязателен'),
password: yup.string().min(6, 'Пароль должен содержать хотя бы 6 символов').required('Пароль обязателен')
});
$: {
emailError = '';
passwordError = '';
try {
schema.validateSync({ email, password }, { abortEarly: false });
} catch (err) {
err.inner.forEach(e => {
if (e.path === 'email') emailError = e.message;
if (e.path === 'password') passwordError = e.message;
});
}
}
</script>
<form>
<div>
<label for="email">Email:</label>
<input id="email" bind:value={email} type="email" />
{#if emailError}
<p class="error">{emailError}</p>
{/if}
</div>
<div>
<label for="password">Пароль:</label>
<input id="password" bind:value={password} type="password" />
{#if passwordError}
<p class="error">{passwordError}</p>
{/if}
</div>
<button type="submit" disabled={emailError || passwordError}>Отправить</button>
</form>
Реализация валидации в реальном времени в Svelte позволяет создать удобные и интерактивные формы с минимальными усилиями. Используя реактивность и возможности фреймворка, можно быстро реагировать на изменения данных и показывать ошибки до того, как пользователь отправит форму. Это не только улучшает пользовательский опыт, но и помогает предотвращать возможные ошибки при работе с данными.