useFieldArray v4.5

useFieldArray is a custom composition API function that allows you to manage repeatable fields and forms entries and provides common operation helpers.

Basic usage:

vue<template>
  <form @submit="onSubmit" novalidate>
    <div v-for="(field, idx) in fields" :key="field.key">
      <Field :name="`links[${idx}].url`" type="url" />

      <button type="button" @click="remove(idx)">Remove</button>
    </div>

    <button type="button" @click="push({ url: '' })">Add</button>

    <button>Submit</button>
  </form>
</template>

<script>
import { Field, useForm, useFieldArray } from 'vee-validate';

export default {
  components: {
    Field,
  },
  setup() {
    const { handleSubmit } = useForm({
      initialValues: {
        links: [{ id: 1, url: 'https://github.com/logaretm' }],
      },
    });

    const { remove, push, fields } = useFieldArray('links');
    const onSubmit = handleSubmit(values => {
      console.log(JSON.stringify(values, null, 2));
    });

    return {
      fields,
      push,
      remove,
      onSubmit,
    };
  },
};
</script>

API Reference

The full signature of the useFieldArray function looks like this:

tsinterface FieldEntry<TValue = unknown> {
  value: Ref<TValue>;
  key: string | number;
  isFirst: boolean;
  isLast: boolean;
}

interface FieldArrayContext<TValue = unknown> {
  fields: DeepReadonly<Ref<FieldEntry[]>>;
  remove(idx: number): TValue | undefined;
  push(value: TValue): void;
  swap(indexA: number, indexB: number): void;
  insert(idx: number, value: TValue): void;
  update(idx: number, value: TValue): void;
  replace(value: TValue[]): void;
}

function useFieldArray: (arrayPath: string): FieldArrayContext;

Composable API

The following sections documents each available property on the useFieldArray composable.

fields: Ref<FieldArrayEntry<TValue>[]>

This is a read-only version of your array items, wrapped inside a FieldArrayEntry object which has the following interface:

tsinterface FieldEntry<TValue = unknown> {
  // The actual value of the item as readonly, this is what exists in the form values
  value: TValue;
  // a value you can use as a key for iteration, generated by `key-path` prop
  key: string | number;
  // true if this is the first array item
  isFirst: boolean;
  // true if this is the last array item
  isLast: boolean;
}

push(item: any)

Adds an item to the end of the array.

jsconst { push, fields } = useFieldArray('links');

// adds a new item to the array
push({ url: '' });

prepend(item: any)

Adds an item to the start of the array.

jsconst { prepend, fields } = useFieldArray('links');

// adds a new item to the array
prepend({ url: '' });

remove(idx: number)

Removes the item at the specified index from the array if it exists.

jsconst { remove, fields } = useFieldArray('links');

// removes the second item from the array
remove(1);

swap(idxA: number, idxB: number)

Swaps the items at the given indexes with each other. Both indexes must exist in the array or it won't have an effect.

jsconst { swap, fields } = useFieldArray('links');

// Swaps the 4th item with the 5th
swap(3, 4);

insert(idx: number, item: any)

Adds an item at the specified index. If the specified index will place the item out of bounds (i.e: larger than length) the operation will be ignored, you still can add items as the last item of the array.

jsconst { insert, fields } = useFieldArray('links');

// inserts a new item to the array at the second index
insert(1, { url: '' });

update(idx: number, value: any)

Updates the value at the specified index, note that it doesn't merge the values if they are objects. If the specified index is outside the array boundary the operation will be ignored.

jsconst { update, fields } = useFieldArray('links');

// updates the 2nd item value
update(1, { url: '' });

replace(items: any[])

Replaces the entire array of fields.

jsconst { replace, fields } = useFieldArray('links');

// replace the entire array with these items
replace([{ url: 'https://google.com' }, { url: 'https://vuejs.org' }]);