Form Schema — сравнение с VeeValidate и FormKit
VeeValidate и FormKit — оба построены вокруг того, что структура формы описывается в шаблоне компонента: вы пишете <Field>/<FormKit> для каждого поля, а логика (валидация, показ/скрытие, зависимые опции) навешивается на эту разметку. Это удобно, когда форма известна заранее и не меняется во время выполнения.
Form Schema решает другую задачу — форму, структура которой сама является данными: приходит с сервера, собирается из CMS, зависит от роли пользователя или от ответа предыдущего шага визарда. Вместо разметки — массив FieldDefinition, вместо шаблона — useForm(schema), который умеет отрисовать что угодно поверх этой схемы (headless — своя вёрстка, ui-themes — готовая).
Где это действительно имеет значение
- Форма меняется во время выполнения.
visible/disabled/optionsвFieldDefinitionпринимают функции от текущих значений формы — поле само решает, показываться ли, ещё до того, как вы напишетеv-ifв шаблоне. В VeeValidate/FormKit та же логика — это код в шаблоне компонента, который приходится писать заново для каждой такой формы. - Схема приходит с сервера. Если конструктор форм на бэкенде отдаёт JSON, из него можно собрать
FieldDefinition[]напрямую — рендерить компонент с условной разметкой на 30 полей никто вручную генерировать не будет. - SSR без хаков.
useForm()не трогает DOM при инициализации — состояние формы существует независимо от того, где именно она будет отрисована. - Схема валидации не одна.
validators/asyncValidatorsпринимают обычные функции, но при желании тем же полем можно подключить готовую Zod/Yup/Valibot схему — не нужно переучиваться, если в проекте уже есть валидация на одной из них.
Где VeeValidate/FormKit по-прежнему естественнее
Если форма статична и известна на этапе написания кода (логин, форма обратной связи, чек-аут в 5 полей) — писать FieldDefinition[] вместо разметки часто просто лишний уровень косвенности. Form Schema создан для форм, которые меняются, а не для замены разметки формы ради самой замены.