Як використовувати reactive для форми?
reactive зручно використовувати для форми, коли у тебе багато полів, і ти хочеш зберігати їх в одному об'єкті, а не в десятку окремих ref.
Найпростіше так:
Робимо один
reactive-об'єктform, прив'язуємо його поля черезv-modelі працюємо з ним як зі звичайним JS-об'єктом.
Базовий приклад форми з reactive
vue
<script setup>
import { reactive } from 'vue'
const form = reactive({
name: '',
email: '',
age: null,
agree: false,
})
function submit() {
console.log('Відправлення форми:', { ...form })
}
</script>
<template>
<form @submit.prevent="submit">
<input v-model="form.name" placeholder="Ім'я" />
<input v-model="form.email" placeholder="Email" />
<input v-model.number="form.age" type="number" placeholder="Вік" />
<label>
<input type="checkbox" v-model="form.agree" />
Погоджуюсь з умовами
</label>
<button type="submit">Надіслати</button>
</form>
</template>Що важливо:
form- один реактивний об'єкт.- У шаблоні просто пишемо
v-model="form.field". - Жодних
.value- зreactiveпрацюємо як зі звичайним об'єктом.
Скидання форми з reactive
Зазвичай роблять так:
js
const initialForm = {
name: '',
email: '',
age: null,
agree: false,
}
const form = reactive({ ...initialForm })
function reset() {
Object.assign(form, initialForm)
}У шаблоні:
html
<button type="button" @click="reset">Скинути</button>Так form залишається тим самим реактивним об'єктом, але його поля повертаються у вихідний стан.
Валідація з reactive
Можна зробити об'єкт помилок:
js
const form = reactive({
email: '',
password: '',
})
const errors = reactive({
email: '',
password: '',
})
function validate() {
errors.email = ''
errors.password = ''
if (!form.email.includes('@')) {
errors.email = 'Некоректний email'
}
if (form.password.length < 6) {
errors.password = 'Мінімум 6 символів'
}
return !errors.email && !errors.password
}
function submit() {
if (!validate()) return
// відправлення
}Шаблон:
html
<input v-model="form.email" />
<p v-if="errors.email" class="error">{{ errors.email }}</p>reactive vs ref для форми
Коли краще reactive:
- багато полів форми -> зручно тримати в одному об'єкті;
- потрібно передати всю форму кудись цілком (у функцію / API);
- є вкладені структури (
address.city,profile.contacts.phone).
Коли ref теж ок:
- одне-два поля;
- прості компоненти, де об'єкт надлишковий.
Нюанс: не деструктурувати reactive у шаблоні
Якщо зробити так:
js
const form = reactive({ name: '', email: '' })
const { name, email } = form // так втрачається реактивністьТо в шаблоні:
html
<input v-model="name" />реактивність уже не працюватиме коректно.
Правильно або:
html
<input v-model="form.name" />або використовувати toRefs(form), якщо дуже хочеться деструктурувати:
js
import { reactive, toRefs } from 'vue'
const form = reactive({ name: '', email: '' })
const { name, email } = toRefs(form) // добреСпостереження за формою (watch)
Наприклад, автозбереження чернетки:
js
import { reactive, watch } from 'vue'
const form = reactive({
title: '',
content: '',
})
watch(
() => ({ ...form }), // створюємо новий об'єкт, щоб watch бачив зміни
(val) => {
console.log('Зберігаємо чернетку', val)
},
{ deep: true }
)Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.