Найпростіший підхід - один реактивний об'єкт з усіма полями форми і v-model на кожному полі:
<script setup lang="ts">
import { reactive, ref } from 'vue'
const initial = () => ({ name: '', email: '', role: 'editor', agree: false })
const form = reactive(initial())
const submitting = ref(false)
async function submit() {
submitting.value = true
try {
await api.post('/users', { ...form })
Object.assign(form, initial()) // скидання
} finally {
submitting.value = false
}
}
</script>
<template>
<form @submit.prevent="submit">
<input v-model.trim="form.name" />
<input v-model="form.email" type="email" />
<select v-model="form.role">
<option value="editor">Редактор</option>
<option value="admin">Адміністратор</option>
</select>
<input v-model="form.agree" type="checkbox" />
<button :disabled="submitting">Зберегти</button>
</form>
</template>
reactive чи ref:
reactive({...}) |
ref({...}) |
|
|---|---|---|
доступ у <script> |
form.email |
form.value.email |
| замінити весь об'єкт | ні - лише Object.assign |
так: form.value = initial() |
| деструктуризація | ламає реактивність | теж ламає (form.value - реактивний об'єкт) |
ref зручніший, коли форму треба повністю замінити (завантажили дані для редагування). reactive - коротший запис полів.
Модифікатори v-model: .trim прибирає пробели, .number перетворює на число, .lazy оновлює значення на change, а не на кожен введений символ.
Типові помилки:
@submitбез.prevent- браузер відправляє форму звичайним запитом і перезавантажує сторінку;- скидання через
form = initial()дляreactive- зміниться лише локальна змінна, а шаблон лишиться прив'язаним до старого об'єкта; - відправка самого реактивного проксі - бібліотеки зазвичай серіалізують його коректно, але безпечніше передавати звичайну копію (
{ ...form }чиtoRaw(form)); - checkbox для масиву: кілька чекбоксів з одним
v-modelі масивом у стані дають список вибраних значень; - немає захисту від подвійного кліку - кнопка має бути вимкнена на час відправки.
Для складних форм (валідація, вкладені масиви, стан «змінено») варто взяти бібліотеку форм, а не винаходити все самому.