Интеграция с Vuelidate

Для работы с формами в Vuetify часто используют библиотеку Vuelidate, которая обеспечивает декларативную валидацию данных. Установка производится через npm или yarn:

npm install @vuelidate/core @vuelidate/validators

или

yarn add @vuelidate/core @vuelidate/validators

После установки необходимо подключить Vuelidate в компоненте:

import { useVuelidate } from '@vuelidate/core'
import { required, minLength, email } from '@vuelidate/validators'

Далее создаётся объект правил валидации и связывается с состоянием формы через реактивные свойства Vue.


Создание реактивной формы

Vuetify предоставляет компоненты v-form, v-text-field, v-select и другие, которые интегрируются с Vuelidate. Сначала создаётся реактивное состояние формы:

import { reactive } from 'vue'

export default {
  setup() {
    const form = reactive({
      name: '',
      email: '',
      password: ''
    })

    const rules = {
      name: { required },
      email: { required, email },
      password: { required, minLength: minLength(6) }
    }

    const v$ = useVuelidate(rules, form)

    return { form, v$ }
  }
}

Ключевые моменты:

  • reactive создаёт реактивное состояние формы, на которое будут ссылаться поля ввода.
  • rules описывает все правила валидации для каждого поля.
  • v$ — объект Vuelidate, который хранит состояние валидации.

Интеграция с компонентами Vuetify

Для привязки Vuelidate к компонентам Vuetify используют свойства error, error-messages и методы проверки:

<v-form @submit.prevent="submitForm" ref="formRef">
  <v-text-field
    label="Имя"
    v-model="form.name"
    :error="v$.name.$invalid && v$.name.$dirty"
    :error-messages="v$.name.$errors.map(e => e.$message)"
    @blur="v$.name.$touch()"
  ></v-text-field>

  <v-text-field
    label="Email"
    v-model="form.email"
    :error="v$.email.$invalid && v$.email.$dirty"
    :error-messages="v$.email.$errors.map(e => e.$message)"
    @blur="v$.email.$touch()"
  ></v-text-field>

  <v-text-field
    label="Пароль"
    type="password"
    v-model="form.password"
    :error="v$.password.$invalid && v$.password.$dirty"
    :error-messages="v$.password.$errors.map(e => e.$message)"
    @blur="v$.password.$touch()"
  ></v-text-field>

  <v-btn type="submit" color="primary">Отправить</v-btn>
</v-form>

Особенности интеграции:

  • v$.field.$invalid определяет, нарушено ли правило.
  • v$.field.$dirty указывает, было ли поле изменено пользователем.
  • $touch() помечает поле как “затронутое”, вызывая отображение ошибок.
  • Ошибки формируются через v$.field.$errors.map(e => e.$message), что позволяет использовать кастомные сообщения.

Кастомные сообщения об ошибках

Vuelidate позволяет определять свои тексты ошибок с помощью параметров валидаторов:

import { required, minLength } from '@vuelidate/validators'

const rules = {
  name: { required: required.$message('Поле "Имя" обязательно') },
  password: {
    required: required.$message('Пароль обязателен'),
    minLength: minLength(6).$message('Минимальная длина пароля — 6 символов')
  }
}

Это улучшает пользовательский опыт, так как каждое правило сопровождается понятным сообщением.


Валидация формы при отправке

Проверка всей формы перед отправкой реализуется через метод $validate:

const submitForm = async () => {
  v$.$touch()
  if (await v$.$validate()) {
    console.log('Форма валидна', form)
  } else {
    console.log('Есть ошибки')
  }
}

Принципы работы:

  • $touch() отмечает все поля как изменённые, чтобы сразу показать ошибки.
  • $validate() возвращает true, если все правила пройдены.
  • Асинхронная проверка позволяет использовать кастомные валидаторы с API-запросами.

Асинхронные и условные валидаторы

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

import { helpers } from '@vuelidate/validators'

const rules = {
  username: {
    required,
    unique: helpers.withAsync(async value => {
      if (!value) return true
      const response = await fetch(`/api/check-username?username=${value}`)
      const data = await response.json()
      return data.available
    }).$message('Имя пользователя уже занято')
  }
}

Особенности:

  • helpers.withAsync позволяет создавать валидаторы с асинхронными вызовами.
  • Можно комбинировать несколько валидаторов через объект.
  • Подходит для проверки уникальности, загрузки данных и интеграции с серверной логикой.

Связь Vuelidate с динамическими формами Vuetify

Для динамических форм, где поля создаются на основе массива данных, правила валидации можно строить программно:

const fields = reactive([
  { name: 'email', value: '', rules: { required, email } },
  { name: 'phone', value: '', rules: { required } }
])

const dynamicRules = {}
fields.forEach(f => {
  dynamicRules[f.name] = f.rules
})

const v$ = useVuelidate(dynamicRules, fields.reduce((acc, f) => {
  acc[f.name] = f.value
  return acc
}, {}))

Такой подход позволяет масштабировать форму и автоматически обновлять валидацию при добавлении новых полей.


Поддержка Vuetify 3

Vuetify 3 использует Composition API, что делает интеграцию с Vuelidate более естественной. Ключевые моменты:

  • Использовать reactive или ref для состояния формы.
  • v-model поддерживается для всех input-компонентов.
  • Ошибки и состояния валидации ($invalid, $dirty, $errors) легко связываются через props компонентов Vuetify.
  • Асинхронная валидация и кастомные сообщения полностью совместимы с Vuetify 3.

Эта интеграция позволяет создавать формы с гибкой и масштабируемой валидацией, полностью используя возможности Vuetify и реактивность Vue.