Обработка отправки форм

В Vuetify формы строятся на базе компонентов <v-form> и разнообразных элементов ввода, таких как <v-text-field>, <v-select>, <v-checkbox> и других. Основной принцип — объединение всех полей формы внутри <v-form> для централизованного контроля валидации и состояния формы.

<v-form ref="formRef" v-model="isFormValid">
  <v-text-field
    v-model="formData.name"
    :rules="[rules.required]"
    label="Имя"
    required
  ></v-text-field>

  <v-text-field
    v-model="formData.email"
    :rules="[rules.required, rules.email]"
    label="Email"
    required
  ></v-text-field>

  <v-btn @click="submitForm" :disabled="!isFormValid">Отправить</v-btn>
</v-form>
  • v-model на <v-form> связывает состояние валидации формы с переменной isFormValid.
  • ref позволяет получить доступ к методам формы, например, для программной валидации this.$refs.formRef.validate().
  • Каждое поле принимает массив правил :rules, которые проверяются автоматически при изменении значения.

Создание и использование правил валидации

Правила в Vuetify — это функции, возвращающие true при успешной проверке или строку с сообщением об ошибке при нарушении. Например:

rules: {
  required: value => !!value || 'Поле обязательно для заполнения',
  email: value => /.+@.+\..+/.test(value) || 'Неверный формат email'
}

Для более сложной логики можно использовать асинхронные правила, проверяющие данные на сервере перед отправкой формы.

Программная валидация и сброс формы

Методы <v-form> предоставляют возможности для полной проверки и очистки формы:

methods: {
  submitForm() {
    if (this.$refs.formRef.validate()) {
      this.sendData();
    }
  },
  resetForm() {
    this.$refs.formRef.reset();
  }
}
  • validate() проверяет все правила формы и возвращает true или false.
  • reset() сбрасывает значения полей к исходным и очищает ошибки.
  • resetValidation() сбрасывает только сообщения об ошибках без изменения значений.

Асинхронная отправка данных

Для отправки формы на сервер рекомендуется использовать асинхронные методы с обработкой ошибок:

async sendData() {
  try {
    await axios.post('/api/submit', this.formData);
    this.resetForm();
    this.$toast.success('Форма успешно отправлена');
  } catch (error) {
    this.$toast.error('Ошибка отправки формы');
  }
}
  • Состояние кнопки можно динамически привязать к isFormValid или к переменной isSubmitting, чтобы предотвратить повторные клики.
  • Отображение состояния загрузки удобно реализовать с помощью свойства loading на <v-btn>:
<v-btn :loading="isSubmitting" :disabled="!isFormValid" @click="submitForm">
  Отправить
</v-btn>

Работа с динамическими формами

Vuetify поддерживает динамическое создание полей формы на основе массивов или объектов. Например:

<v-form ref="dynamicForm" v-model="dynamicValid">
  <v-text-field
    v-for="(field, index) in dynamicFields"
    :key="index"
    v-model="field.value"
    :label="field.label"
    :rules="field.rules"
    required
  ></v-text-field>
</v-form>
  • Такой подход позволяет гибко добавлять или удалять поля, сохраняя централизованную валидацию.
  • Для массивов объектов удобно использовать v-for с генерацией правил и отслеживанием состояния каждого поля.

Пользовательские компоненты форм

Создание кастомных компонентов ввода, совместимых с <v-form>, требует реализации v-model и методов validate и resetValidation. Пример:

<template>
  <v-text-field
    v-model="internalValue"
    :error-messages="errors"
    @input="$emit('update:modelValue', internalValue)"
  ></v-text-field>
</template>

<script>
export default {
  props: {
    modelValue: String,
    rules: Array
  },
  data() {
    return {
      internalValue: this.modelValue,
      errors: []
    }
  },
  methods: {
    validate() {
      this.errors = this.rules
        .map(rule => rule(this.internalValue))
        .filter(msg => msg !== true);
      return this.errors.length === 0;
    },
    resetValidation() {
      this.errors = [];
    }
  },
  watch: {
    modelValue(val) {
      this.internalValue = val;
    }
  }
}
</script>
  • Такой компонент полностью интегрируется с <v-form> и поддерживает как стандартные, так и кастомные правила.

Подключение уведомлений и индикаторов состояния

Для UX важно отображать пользователю ошибки или успех после отправки формы. Vuetify позволяет сочетать v-alert, v-snackbar и v-progress-circular для отображения состояния:

<v-snackbar v-model="showMessage">{{ message }}</v-snackbar>
<v-progress-circular v-if="isSubmitting" indeterminate color="primary"></v-progress-circular>
  • Переменные showMessage, message и isSubmitting управляют отображением уведомлений и индикаторов.
  • Такой подход делает формы интерактивными и информативными, повышая удобство пользователя.

Интеграция с Vuex и Composition API

Для больших приложений состояние формы удобно хранить в Vuex или reactive объектах Composition API:

import { reactive, ref } from 'vue';

const formData = reactive({
  name: '',
  email: ''
});

const formRef = ref(null);

function submit() {
  if (formRef.value.validate()) {
    store.dispatch('submitForm', formData);
  }
}
  • reactive позволяет автоматически отслеживать изменения всех полей.
  • ref для <v-form> обеспечивает доступ к методам валидации и сброса.

Эти подходы создают масштабируемую и управляемую систему форм, подходящую для сложных приложений на Vuetify.