В Vuetify формы строятся на основе компонентов v-form,
которые обеспечивают управление состоянием формы, валидацию и интеграцию
с различными элементами интерфейса. Для сложных форм критически важно
правильно структурировать компоненты и использовать реактивность Vue для
отслеживания данных.
Основные элементы:
validate(), reset(),
resetValidation().Каждое поле формы в Vuetify связано с переменной в data
или ref через v-model. Это обеспечивает
двустороннюю привязку данных и позволяет отслеживать изменения в режиме
реального времени. Для сложных форм с динамическими полями используется
массив объектов:
data() {
return {
users: [
{ name: '', email: '', role: '' }
],
roles: ['Admin', 'Editor', 'Viewer']
}
}
Каждый элемент массива может быть визуализирован через
v-for, создавая повторяющиеся блоки формы с индивидуальной
валидацией.
<v-form ref="userForm">
<v-row v-for="(user, index) in users" :key="index">
<v-col cols="4">
<v-text-field v-model="user.name" label="Имя" :rules="[v => !!v || 'Обязательное поле']"/>
</v-col>
<v-col cols="4">
<v-text-field v-model="user.email" label="Email" :rules="[v => /.+@.+\..+/.test(v) || 'Неверный email']"/>
</v-col>
<v-col cols="4">
<v-select v-model="user.role" :items="roles" label="Роль"/>
</v-col>
</v-row>
</v-form>
Vuetify поддерживает как синхронную, так и асинхронную валидацию.
Основной механизм – массив функций rules для каждого поля.
Каждая функция возвращает true при успешной проверке или
строку с сообщением об ошибке. Для асинхронной валидации используется
метод async/await внутри кастомной функции.
async function validateEmail(email) {
const response = await fetch(`/api/check-email?email=${email}`);
const { valid } = await response.json();
return valid || 'Email уже используется';
}
<v-text-field
v-model="user.email"
label="Email"
:rules="[v => !!v || 'Обязательное поле', validateEmail]"
/>
Методы формы this.$refs.userForm.validate() и
reset() позволяют программно управлять валидностью и
сбросом формы.
Для сложных форм часто требуется возможность добавлять и удалять
группы полей. Это реализуется через реактивные массивы и методы
push/splice:
methods: {
addUser() {
this.users.push({ name: '', email: '', role: '' });
},
removeUser(index) {
this.users.splice(index, 1);
}
}
<v-btn @click="addUser">Добавить пользователя</v-btn>
<v-btn @click="removeUser(index)" v-for="(user, index) in users" :key="index">Удалить</v-btn>
Vuetify позволяет изменять визуальное представление полей через слоты:
prepend-inner и append-inner – вставка
иконок или кнопок внутрь поля.label – кастомный рендеринг подписи.default – полное переопределение компонента.Пример кастомного поля с иконкой:
<v-text-field
v-model="user.name"
label="Имя"
>
<template v-slot:prepend-inner>
<v-icon>mdi-account</v-icon>
</template>
</v-text-field>
Для очень больших форм удобно использовать многошаговые
формы через v-stepper:
<v-stepper v-model="step">
<v-stepper-header>
<v-stepper-step step="1" :complete="step > 1">Основная информация</v-stepper-step>
<v-stepper-step step="2">Контакты</v-stepper-step>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<!-- поля первого шага -->
<v-btn @click="step++">Далее</v-btn>
</v-stepper-content>
<v-stepper-content step="2">
<!-- поля второго шага -->
<v-btn @click="step--">Назад</v-btn>
<v-btn @click="submitForm">Отправить</v-btn>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
Сложные формы часто требуют интеграции с календарями, масками ввода,
редакторами текста. Vuetify совместим с большинством Vue-библиотек.
Например, для маски ввода используется vue-the-mask:
<v-text-field
v-mask="'###-###-####'"
v-model="user.phone"
label="Телефон"
/>
Для редактора текста можно внедрить quill или
tiptap внутри v-card или
v-expansion-panel, сохраняя реактивность через
v-model.
В сложных формах критически важно отображать ошибки аккуратно:
error-messages для ручного управления
ошибками.:error="hasError(field)".:disabled="!formIsValid".computed: {
formIsValid() {
return this.$refs.userForm?.validate() || false;
}
}
Такой подход позволяет создавать формы с высоким уровнем интерактивности, динамическими блоками и сложной логикой валидации, оставаясь в рамках реактивной модели Vue и гибкой структуры Vuetify.