In the previous guide I showed how to make a compound input for a person’s first and last name. Suppose that we now want to show this input for a variable number of people, how should that be done?
We will start with a root data object that will contain all the data for our form, updated dynamically as the form inputs are changed.
const formData = {
people: [],
};
The form will contain a list of “Person” inputs, and a button to add a new person.
<template>
<div style="border: 1px solid black">
<person
v-for="(person, index) in props.value"
:key="index"
:value="person"
/>
<button @click.prevent="addPerson">Add Person</button>
</div>
</template>
<script setup>
import Person from "@/Person.vue";
const props = defineProps({ value: Array });
const addPerson = function () {
props.value.push({ firstName: "", lastName: "" });
};
</script>
And the Person input simply contains the two text input fields:
<template>
<div>
<input type="text" v-model="props.value.firstName" />
<input type="text" v-model="props.value.lastName" />
</div>
</template>
<script setup>
const props = defineProps({ value: Object });
</script>
Things to Note
It’s important to realise that the updating of data is handled by Vue3’s object reactivity API, and NOT by its event system. This has two implications:
- Form values are passed in the
:value
attribute, not inv-model
. - Form values passed in
:value
must be objects. Simple types (strings, numbers) will not work.