I am using Vue3 with the Composition API and Pinia. When building a form component with various input fields, I've been handling it like this example, where each input is assigned it's own variable (binding to v-model) and then returned:
// UserForm.vue
<template>
<div>
<form @submit.prevent="addUser">
<div><input v-model="firstName" type="text" /></div>
<div><input v-model="lastName" type="text" /></div>
<div><input v-model="email" type="text" /></div>
// Lots more inputs
</form>
</div>
</template>
<script>
import { ref } from "vue";
import { useUserStore } from "../store/useUserStore";
export default {
setup() {
const firstName = ref("");
const lastName = ref("");
const email = ref("");
const userStore = useUserStore();
function addUser(firstName, lastName, email) {
userStore.addUser(firstName, lastName, email);
}
return { firstName, lastName, email, addUser, userStore };
},
};
</script>
// useUserStore.js
import { defineStore } from "pinia";
export const useUserStore = defineStore('user', {
state: () => ({
users: [],
}),
actions: {
addUser(firstName, lastName, email) {
this.users.push({ firstName, lastName, email })
},
},
});
I would prefer to assign all form inputs to a formData object and simply return the object (instead of a long list of individual variables). Then the template would look like this:
<template>
<div>
<form @submit.prevent="addUser">
<div><input v-model="formData.firstName" type="text" /></div>
<div><input v-model="formData.lastName" type="text" /></div>
<div><input v-model="formData.email" type="text" /></div>
// Lots more inputs
</form>
</div>
</template>
Is this possible? How do I use an object for v-model bindings to store all form inputs?
I tried using a formData object like this but it's not correct:
const formData = {
firstName: ref(""),
lastName: ref(""),
email: ref("")
};
You can achieve the desired result using Vue's reactive()
method. Here's a link to the documentation
So you would do this instead:
const formData = reactive({
firstName: "",
lastName: "",
email: ""
});
and can access the values in the template as such:
<template>
<div>
<form @submit.prevent="addUser">
<div><input v-model="formData.firstName" type="text" /></div>
<div><input v-model="formData.lastName" type="text" /></div>
<div><input v-model="formData.email" type="text" /></div>
// Lots more inputs
</form>
</div>
</template>
I hope that helps.