В современной веб-разработке валидация форм является критически важной частью пользовательского опыта. В этой статье я покажу, как интегрировать мощную библиотеку валидации Valibot с формами UForm из модуля @nuxt/ui в Nuxt 3.
Что такое Valibot?
Valibot — это легковесная библиотека для валидации данных с TypeScript-first подходом. Она предлагает:
- Отличную производительность
- Полную TypeScript-поддержку
- Гибкость и модульность
- Простоту использования
Установка необходимых зависимостей
Сначала установим необходимые пакеты:
npm install valibot
# или
yarn add valibot
Модуль @nuxt/ui уже должен быть установлен в вашем проекте Nuxt 3.
Создание схемы валидации с Valibot
Создадим файл schemas/contact.ts
для хранения наших схем валидации:
import { string, minLength, email, object, type Output } from 'valibot';
// Схема для контактной формы
export const ContactSchema = object({
name: string([minLength(2, 'Имя должно содержать минимум 2 символа')]),
email: string([email('Введите корректный email адрес')]),
message: string([minLength(10, 'Сообщение должно содержать минимум 10 символов')]),
});
// Тип для TypeScript на основе схемы
export type ContactFormData = Output<typeof ContactSchema>;
Создание компонента формы
Теперь создадим компонент формы в components/ContactForm.vue
:
<script setup lang="ts">
import { validate } from 'valibot';
import { ContactSchema, type ContactFormData } from '~/schemas/contact';
const state = reactive({
name: '',
email: '',
message: '',
errors: {} as Record<string, string>,
});
const isLoading = ref(false);
async function onSubmit() {
// Очищаем предыдущие ошибки
state.errors = {};
try {
// Валидируем данные с помощью Valibot
const result = validate(ContactSchema, state);
// Если валидация прошла успешно, обрабатываем форму
isLoading.value = true;
// Здесь может быть вызов API или другая логика обработки
console.log('Форма отправлена:', result);
// Сброс формы после успешной отправки
state.name = '';
state.email = '';
state.message = '';
// Показываем уведомление об успехе
useToast().add({ title: 'Форма отправлена успешно!' });
} catch (error) {
// Обрабатываем ошибки валидации
if (error instanceof Error) {
const fieldErrors = JSON.parse(error.message);
for (const error of fieldErrors) {
state.errors[error.path[0].key] = error.message;
}
}
} finally {
isLoading.value = false;
}
}
</script>
<template>
<UForm :state="state" @submit="onSubmit">
<UFormGroup label="Имя" name="name" :error="state.errors.name">
<UInput v-model="state.name" />
</UFormGroup>
<UFormGroup label="Email" name="email" :error="state.errors.email" class="mt-4">
<UInput v-model="state.email" type="email" />
</UFormGroup>
<UFormGroup label="Сообщение" name="message" :error="state.errors.message" class="mt-4">
<UTextarea v-model="state.message" />
</UFormGroup>
<UButton type="submit" class="mt-4" :loading="isLoading">
Отправить
</UButton>
</UForm>
</template>
Альтернативный подход: Композиция useValidate
Для более удобного повторного использования можно создать композицию useValidate
:
// composables/useValidate.ts
import { validate, type BaseSchema } from 'valibot';
export function useValidate<T extends BaseSchema>(schema: T) {
const errors = ref<Record<string, string>>({});
const validateForm = (data: any) => {
try {
errors.value = {};
const result = validate(schema, data);
return { valid: true, data: result };
} catch (error) {
if (error instanceof Error) {
const fieldErrors = JSON.parse(error.message);
for (const err of fieldErrors) {
errors.value[err.path[0].key] = err.message;
}
}
return { valid: false, errors: errors.value };
}
};
return { errors, validateForm };
}
Теперь можно упростить наш компонент формы:
<script setup lang="ts">
import { ContactSchema } from '~/schemas/contact';
const { errors, validateForm } = useValidate(ContactSchema);
const state = reactive({
name: '',
email: '',
message: '',
});
async function onSubmit() {
const { valid } = validateForm(state);
if (!valid) return;
// Логика отправки формы...
}
</script>
Преимущества такого подхода
- Типобезопасность: TypeScript подсказывает типы полей формы
- Переиспользование: Схемы валидации можно использовать на фронтенде и бэкенде
- Производительность: Valibot очень легковесен
- Интеграция: Плавная работа с @nuxt/ui формами
Заключение
Интеграция Valibot с формами UForm в Nuxt 3 предоставляет мощное и типобезопасное решение для валидации данных. Такой подход сочетает в себе удобство использования готовых UI-компонентов из @nuxt/ui с гибкостью и надежностью библиотеки Valibot.
Попробуйте этот подход в своем следующем проекте на Nuxt 3, и вы оцените его преимущества!
Добавить комментарий