Dynamic Forms
Dynamic array fields
Schema definition
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 },
],
},
]Sub-field names are bare ('name', not 'members.name') — useFieldArray prefixes them to 'members.0.name', 'members.1.name', ... per row itself; a pre-prefixed name would end up doubled ('members.0.members.name').
FormRenderer renders an ArrayField automatically with Add / Remove buttons.
useFieldArray composable
import { useFieldArray } from '@macrulez/vue-form-schema'
const { rows, count, append, prepend, remove, move, swap, replace } = useFieldArray(form, 'members')| Method | Description |
|---|---|
append(defaults?) | Add a row at the end |
prepend(defaults?) | Add a row at the beginning |
remove(index) | Remove a row |
move(from, to) | Move a row |
swap(a, b) | Swap two rows |
replace(index, defaults?) | Replace a row with fresh defaults |
rows is a ComputedRef<FieldArrayRow[]>. Each row exposes index, key, and fields — the nested FieldDefinition[] with prefixed paths for that row.
Multi-step forms
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)
},
)| Property / Method | Description |
|---|---|
currentStep | Ref<number> — 0-based index |
totalSteps | Number of steps |
isFirstStep / isLastStep | ComputedRef<boolean> |
form | UseFormReturn for the current step |
values | All values across all steps merged |
next() | Validate current step then advance (returns false if invalid) |
back() | Go to previous step |
goTo(n) | Jump to step n |
submit() | Validate all steps then call onSubmit |
MultiStepFormRenderer
import { MultiStepFormRenderer } from '@macrulez/vue-form-schema/ui'
<MultiStepFormRenderer :wizard="wizard" />Renders the current step's fields and Back / Next / Submit navigation buttons.
Field transform & parse
const schema: FieldDefinition[] = [
{
type: 'text',
name: 'username',
// trim on every keystroke
transform: (value) => (typeof value === 'string' ? value.trim() : value),
},
{
type: 'text',
name: 'tags',
defaultValue: 'vue,react',
// split into array at submit time — values.tags is still a string
parse: (raw) =>
String(raw)
.split(',')
.map((s) => s.trim()),
},
]transform mutates values immediately. parse runs only at submit time and does not mutate values.
File upload field
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'] is File | null; values['attachments'] is File[] | null.
FormRenderer automatically renders FileField with a drag-and-drop zone and a file list with remove buttons.