Suggest an editImprove this articleRefine the answer for “How to use reactive for a form?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`reactive`** is convenient for a form with many fields, storing them in a single object instead of separate refs. **Key point:** fields are bound with v-model="form.field", and the form is reset with Object.assign(form, initialForm).Shown above the full answer for quick recall.Answer (EN)Image`reactive` is convenient to use for a form when you have **many fields** and want to store them in **a single object** instead of a dozen separate `ref`s. The simplest approach: > **Create one** `reactive` **object** `form`**, bind its fields through** `v-model`**, and work with it like a regular JS object.** --- ## A basic form example with `reactive` ```vue <script setup> import { reactive } from 'vue' const form = reactive({ name: '', email: '', age: null, agree: false, }) function submit() { console.log('Submitting form:', { ...form }) } </script> <template> <form @submit.prevent="submit"> <input v-model="form.name" placeholder="Name" /> <input v-model="form.email" placeholder="Email" /> <input v-model.number="form.age" type="number" placeholder="Age" /> <label> <input type="checkbox" v-model="form.agree" /> I agree to the terms </label> <button type="submit">Submit</button> </form> </template> ``` What matters here: - `form` is a single reactive object. - In the template we just write `v-model="form.field"`. - No `.value` - with `reactive` you work with it like a regular object. --- ## Resetting the form with `reactive` The usual way to do it: ```js const initialForm = { name: '', email: '', age: null, agree: false, } const form = reactive({ ...initialForm }) function reset() { Object.assign(form, initialForm) } ``` In the template: ```html <button type="button" @click="reset">Reset</button> ``` This way `form` stays the same reactive object, but its fields go back to the initial state. --- ## Validation with `reactive` You can make an errors object: ```js const form = reactive({ email: '', password: '', }) const errors = reactive({ email: '', password: '', }) function validate() { errors.email = '' errors.password = '' if (!form.email.includes('@')) { errors.email = 'Invalid email' } if (form.password.length < 6) { errors.password = 'Minimum 6 characters' } return !errors.email && !errors.password } function submit() { if (!validate()) return // submit } ``` Template: ```html <input v-model="form.email" /> <p v-if="errors.email" class="error">{{ errors.email }}</p> ``` --- ## `reactive` vs `ref` for a form When `reactive` is better: - many form fields, convenient to keep in one object; - you need to pass the whole form somewhere at once (into a function / API); - there are nested structures (`address.city`, `profile.contacts.phone`). When `ref` is fine too: - one or two fields; - simple components where an object is excessive. --- ## A nuance: don't destructure `reactive` in the template If you do this: ```js const form = reactive({ name: '', email: '' }) const { name, email } = form // this loses reactivity ``` Then in the template: ```html <input v-model="name" /> ``` reactivity no longer works correctly. The correct way is either: ```html <input v-model="form.name" /> ``` or use `toRefs(form)` if you really want to destructure: ```js import { reactive, toRefs } from 'vue' const form = reactive({ name: '', email: '' }) const { name, email } = toRefs(form) // good ``` --- ## Watching the form (`watch`) For example, autosaving a draft: ```js import { reactive, watch } from 'vue' const form = reactive({ title: '', content: '', }) watch( () => ({ ...form }), // create a new object so watch sees the changes (val) => { console.log('Saving draft', val) }, { deep: true } ) ```For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.