Skip to content

Динамические формы

Динамические массивы полей

Определение схемы

ts
const schema: FieldDefinition[] = [
  {
    type: 'array',
    name: 'members',
    label: 'Team members',
    fields: [
      { type: 'text', name: 'name', label: 'Name', required: true },
      { type: 'email', name: 'email', label: 'Email', required: true },
    ],
  },
]

name подполей — простые ('name', а не 'members.name') — useFieldArray добавляет им префикс 'members.0.name', 'members.1.name', ... для каждой строки; предварительно префиксированное имя задвоилось бы ('members.0.members.name').

FormRenderer автоматически рендерит ArrayField с кнопками добавления/удаления.

Composable useFieldArray

ts
import { useFieldArray } from '@macrulez/vue-form-schema'

const { rows, count, append, prepend, remove, move, swap, replace } = useFieldArray(form, 'members')
МетодОписание
append(defaults?)Добавить строку в конец
prepend(defaults?)Добавить строку в начало
remove(index)Удалить строку
move(from, to)Переместить строку
swap(a, b)Поменять местами две строки
replace(index, defaults?)Заменить строку на новую с defaults

rows — это ComputedRef<FieldArrayRow[]>. Каждая строка предоставляет index, key и fields — вложенный FieldDefinition[] с префиксированными путями для этой строки.

Многошаговые формы

ts
import { useMultiStepForm } from '@macrulez/vue-form-schema'

const wizard = useMultiStepForm(
  [
    { title: 'Account', schema: accountFields },
    { title: 'Profile', schema: profileFields },
    { title: 'Confirm', schema: confirmFields },
  ],
  async (allValues) => {
    await api.register(allValues)
  },
)
Свойство / МетодОписание
currentStepRef<number> — индекс с отсчётом от 0
totalStepsКоличество шагов
isFirstStep / isLastStepComputedRef<boolean>
formUseFormReturn для текущего шага
valuesВсе значения по всем шагам, объединённые вместе
next()Провалидировать текущий шаг и перейти дальше (вернёт false, если невалидно)
back()Вернуться на предыдущий шаг
goTo(n)Перейти на шаг n
submit()Провалидировать все шаги и вызвать onSubmit

MultiStepFormRenderer

vue
import { MultiStepFormRenderer } from '@macrulez/vue-form-schema/ui'

<MultiStepFormRenderer :wizard="wizard" />

Рендерит поля текущего шага и кнопки навигации Назад / Далее / Отправить.

Трансформация и парсинг поля

ts
const schema: FieldDefinition[] = [
  {
    type: 'text',
    name: 'username',
    // обрезка пробелов на каждое нажатие клавиши
    transform: (value) => (typeof value === 'string' ? value.trim() : value),
  },
  {
    type: 'text',
    name: 'tags',
    defaultValue: 'vue,react',
    // разбить на массив во время отправки — values.tags всё ещё строка
    parse: (raw) =>
      String(raw)
        .split(',')
        .map((s) => s.trim()),
  },
]

transform немедленно изменяет values. parse выполняется только во время отправки и не изменяет values.

Поле загрузки файла

ts
import { fileType, fileSize, fileCount } from '@macrulez/vue-form-schema'

const schema: FieldDefinition[] = [
  {
    type: 'file',
    name: 'avatar',
    label: 'Profile photo',
    accept: 'image/*',
    validators: [
      fileType(['image/'], 'Only images are accepted'),
      fileSize(2 * 1024 * 1024, 'Max 2 MB'),
    ],
  },
  {
    type: 'file',
    name: 'attachments',
    label: 'Attachments',
    multiple: true,
    validators: [fileCount(5, 'Up to 5 files')],
  },
]

values['avatar'] — это File | null; values['attachments'] — это File[] | null.

FormRenderer автоматически рендерит FileField с зоной drag-and-drop и списком файлов с кнопками удаления.