Рівень 1 - вбудована валідація браузера: атрибути required, type="email", minlength, pattern, min/max.
<input v-model="form.email" type="email" required />
Безкоштовно й доступно, але повідомлення виглядають по-різному в браузерах, їх важко стилізувати, а складні правила («пароль збігається», «дата закінчення після початку») не виражаються. Атрибут novalidate на формі вимикає перевірку браузера, коли ви робите власну.
Рівень 2 - власна валідація через computed:
const errors = computed(() => ({
email: /^\S+@\S+$/.test(form.email) ? null : 'Некоректна адреса',
password: form.password.length >= 8 ? null : 'Щонайменше 8 символів',
}))
Підходить для двох-трьох полів. Далі починаються стани «поле торкнулися», «форму відправляли», асинхронні перевірки - і код розростається.
Рівень 3 - бібліотека й схема. VeeValidate керує станом полів, а Zod описує правила:
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import { z } from 'zod'
const schema = toTypedSchema(z.object({
email: z.string().email('Некоректна адреса'),
password: z.string().min(8, 'Щонайменше 8 символів'),
}))
const { defineField, errors, handleSubmit, meta } = useForm({ validationSchema: schema })
const [email, emailAttrs] = defineField('email')
const [password, passwordAttrs] = defineField('password')
const onSubmit = handleSubmit(async (values) => {
await api.post('/register', values) // values вже типізовані з схеми
})
Бібліотека дає errors, стан dirty/touched/valid (meta), валідацію на blur чи input, відправку лише валідних даних.
Схема - спільна мова: та сама схема Zod типізує дані форми й відповідь, її можна використати й для перевірки відповіді API.
Що варто знати:
- адаптер
@vee-validate/zodоголошує peer-залежність від певної мажорної версії Zod - перевіряйте сумісність, перш ніж оновлювати Zod до нової мажорної версії; - клієнтська валідація - лише для зручності. Обійти її - справа однієї секунди в DevTools. Справжня перевірка - на сервері, а помилки 422 від Laravel треба показувати поруч із клієнтськими (
setErrors()у VeeValidate); - дублювання правил між Laravel і Zod неминуче - тримайте на клієнті прості правила формату, а бізнес-правила (унікальність, ліміти) - на сервері;
- альтернативи: FormKit (з компонентами полів), Vuelidate, TanStack Form.