File: arrays.md | Updated: 11/15/2025
Search...
+ K
Auto
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Maintainers Partners Support Learn StatsBETA Discord Merch Blog GitHub Ethos Brand Guide
Documentation
Framework
Vue
Version
Latest
Search...
+ K
Menu
Getting Started
Guides
API Reference
Examples
Framework
Vue
Version
Latest
Menu
Getting Started
Guides
API Reference
Examples
On this page
Copy Markdown
TanStack Form supports arrays as values in a form, including sub-object values inside of an array.
To use an array, you can use field.state.value on an array value in conjunction with Index from solid-js :
vue
<script setup lang="ts">
import { useForm } from '@tanstack/vue-form'
const form = useForm({
defaultValues: {
people: [] as Array<{ age: number; name: string }>,
},
onSubmit: ({ value }) => alert(JSON.stringify(value)),
})
</script>
<template>
<form.Field name="people">
<template v-slot="{ field, state }">
<div>
<form.Field
v-for="(_, i) of field.state.value"
:key="i"
:name="`people[${i}].name`"
>
<template v-slot="{ field: subField, state }">
<!-- ... -->
</template>
</form.Field>
</div>
</template>
</form.Field>
</template>
<script setup lang="ts">
import { useForm } from '@tanstack/vue-form'
const form = useForm({
defaultValues: {
people: [] as Array<{ age: number; name: string }>,
},
onSubmit: ({ value }) => alert(JSON.stringify(value)),
})
</script>
<template>
<form.Field name="people">
<template v-slot="{ field, state }">
<div>
<form.Field
v-for="(_, i) of field.state.value"
:key="i"
:name="`people[${i}].name`"
>
<template v-slot="{ field: subField, state }">
<!-- ... -->
</template>
</form.Field>
</div>
</template>
</form.Field>
</template>
This will generate the mapped slot every time you run pushValue on field:
vue
<button @click="field.pushValue({ name: '', age: 0 })" type="button">
Add person
</button>
<button @click="field.pushValue({ name: '', age: 0 })" type="button">
Add person
</button>
Finally, you can use a subfield like so:
vue
<form.Field
v-for="(_, i) of field.state.value"
:key="i"
:name="`people[${i}].name`"
>
<template v-slot="{ field: subField, state }">
<div>
<label>
<div>Name for person {{ i }}</div>
<input
:value="subField.state.value"
@input="
(e) =>
subField.handleChange(
(e.target as HTMLInputElement).value,
)
"
/>
</label>
</div>
</template>
</form.Field>
<form.Field
v-for="(_, i) of field.state.value"
:key="i"
:name="`people[${i}].name`"
>
<template v-slot="{ field: subField, state }">
<div>
<label>
<div>Name for person {{ i }}</div>
<input
:value="subField.state.value"
@input="
(e) =>
subField.handleChange(
(e.target as HTMLInputElement).value,
)
"
/>
</label>
</div>
</template>
</form.Field>
vue
<script setup lang="ts">
import { useForm } from '@tanstack/vue-form'
const form = useForm({
defaultValues: {
people: [] as Array<{ age: number; name: string }>,
},
onSubmit: ({ value }) => alert(JSON.stringify(value)),
})
</script>
<template>
<form
@submit="
(e) => {
e.preventDefault()
e.stopPropagation()
form.handleSubmit()
}
"
>
<div>
<form.Field name="people">
<template v-slot="{ field, state }">
<div>
<form.Field
v-for="(_, i) of field.state.value"
:key="i"
:name="`people[${i}].name`"
>
<template v-slot="{ field: subField, state }">
<div>
<label>
<div>Name for person {{ i }}</div>
<input
:value="subField.state.value"
@input="
(e) =>
subField.handleChange(
(e.target as HTMLInputElement).value,
)
"
/>
</label>
</div>
</template>
</form.Field>
<button
@click="field.pushValue({ name: '', age: 0 })"
type="button"
>
Add person
</button>
</div>
</template>
</form.Field>
</div>
<form.Subscribe>
<template v-slot="{ canSubmit, isSubmitting }">
<button type="submit" :disabled="!canSubmit">
{{ isSubmitting ? '...' : 'Submit' }}
</button>
</template>
</form.Subscribe>
</form>
</template>
<script setup lang="ts">
import { useForm } from '@tanstack/vue-form'
const form = useForm({
defaultValues: {
people: [] as Array<{ age: number; name: string }>,
},
onSubmit: ({ value }) => alert(JSON.stringify(value)),
})
</script>
<template>
<form
@submit="
(e) => {
e.preventDefault()
e.stopPropagation()
form.handleSubmit()
}
"
>
<div>
<form.Field name="people">
<template v-slot="{ field, state }">
<div>
<form.Field
v-for="(_, i) of field.state.value"
:key="i"
:name="`people[${i}].name`"
>
<template v-slot="{ field: subField, state }">
<div>
<label>
<div>Name for person {{ i }}</div>
<input
:value="subField.state.value"
@input="
(e) =>
subField.handleChange(
(e.target as HTMLInputElement).value,
)
"
/>
</label>
</div>
</template>
</form.Field>
<button
@click="field.pushValue({ name: '', age: 0 })"
type="button"
>
Add person
</button>
</div>
</template>
</form.Field>
</div>
<form.Subscribe>
<template v-slot="{ canSubmit, isSubmitting }">
<button type="submit" :disabled="!canSubmit">
{{ isSubmitting ? '...' : 'Submit' }}
</button>
</template>
</form.Subscribe>
</form>
</template>
