---
title: "ArrayField"
description: "Render array items with stable identities and mutation methods that keep values, state, and errors aligned."
canonical_url: "https://notformdocs.vercel.app/docs/components/array-field"
---

> Index of every page on this site: [llms.txt](https://notformdocs.vercel.app/llms.txt)

`ArrayField` renders no element. It exposes an array field instance through its default slot. Create the instance with `form.arrayField(path)`.

## Usage

<code-collapse>

```vue
<template>
  <ArrayField
    v-slot="{ arrayField }"
    :array-field="form.arrayField('tags')"
  >
    <div
      v-for="item in arrayField.items"
      :key="item.id"
    >
      <Field
        v-slot="{ field }"
        :field="item"
      >
        <input
          v-model="field.model"
          v-bind="field.events"
          aria-label="Tag"
        >

        <FieldError :errors="field" />
      </Field>

      <button
        type="button"
        @click="arrayField.remove(item.index)"
      >
        Remove
      </button>
    </div>

    <FieldError :errors="arrayField" />

    <button
      type="button"
      @click="arrayField.append('')"
    >
      Add tag
    </button>
  </ArrayField>
</template>
```

</code-collapse>

<caution>

Use `item.id` as the Vue key. `index` and `path` change with position. `id` does not.

</caution>

## Props

<field-group>
<field :required="true" name="array-field" type="ArrayFieldInstance<TItem>">

The array field created by `form.arrayField(path)`.

</field>
</field-group>

## Slot props

The default slot receives `arrayField`. Extra attributes passed to `ArrayField` arrive as additional slot props.

### Field members

An array field has the regular field members `model`, `events`, `path`, `id`, `errors`, `isDirty`, `isTouched`, `isValid`, `isValidating`, and `validate()`, with these array-specific semantics:

- `errors` and `isValid` refer to issues at the array's **own** path, such as a minimum item count.
- `isDirty` compares the whole array, so nested edits count.
- `isValidating` includes validation of fields nested in its items.

### Array members

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        items
      </code>
    </td>
    
    <td>
      Item instances, in current order.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        append(value)
      </code>
    </td>
    
    <td>
      Add an item at the end.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        prepend(value)
      </code>
    </td>
    
    <td>
      Add an item at the start.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        insert(index, value)
      </code>
    </td>
    
    <td>
      Insert at an index. Clamped to <code>
        0..length
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        remove(index)
      </code>
    </td>
    
    <td>
      Remove an item and its state. Ignored if out of range.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        move(from, to)
      </code>
    </td>
    
    <td>
      Move an item. Ignored if either index is out of range.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        swap(indexA, indexB)
      </code>
    </td>
    
    <td>
      Swap two items. Ignored if either index is out of range.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        update(index, value)
      </code>
    </td>
    
    <td>
      Replace an item in place. Keeps its id and touched state, drops its old errors. Ignored if out of range.
    </td>
  </tr>
</tbody>
</table>

### Item members

Each entry in `items` is a field for the item's value. It has every field member listed above, plus:

<table>
<thead>
  <tr>
    <th>
      Member
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        index
      </code>
    </td>
    
    <td>
      The item's current position.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        field(path, config?)
      </code>
    </td>
    
    <td>
      A field nested in the item, with a path relative to the item. Cached, and follows the item when it moves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        arrayField(path, config?)
      </code>
    </td>
    
    <td>
      An array field nested in the item.
    </td>
  </tr>
</tbody>
</table>

## Behavior

- Values passed to `append`, `prepend`, `insert`, and `update` are deep-cloned.
- Every mutation counts as a change event on the array field. By default it re-validates the array's own path.
- Errors inside the array are re-pointed to follow their items on every mutation.
- Reset creates fresh item ids.
- A removed item, and anything created from it, becomes inert: mutations do nothing.

Change the array only through these methods. Direct mutation such as `form.values.tags.push('x')` bypasses identity and error tracking. See [Array fields](https://notformdocs.vercel.app/docs/guides/array-fields).

## Related

- [Array fields guide](https://notformdocs.vercel.app/docs/guides/array-fields)
- [Field](https://notformdocs.vercel.app/docs/components/field)

## Sitemap

See the full [sitemap](https://notformdocs.vercel.app/sitemap.md) for all pages.
