Динамические правила

Element Plus предоставляет мощный механизм для работы с формами через компонент ElForm и связанный с ним ElFormItem. Одной из ключевых возможностей является использование динамических правил валидации, позволяющих изменять условия проверки полей формы в зависимости от состояния приложения или других значений.

Основы динамических правил

В стандартной конфигурации правила валидации задаются как массив объектов:

rules: {
  username: [
    { required: true, message: 'Имя пользователя обязательно', trigger: 'blur' },
    { min: 3, max: 12, message: 'Длина от 3 до 12 символов', trigger: 'blur' }
  ]
}

Однако статические правила не всегда подходят для сложных интерфейсов, где условия проверки зависят от других полей. В таких случаях применяются динамические функции, возвращающие правила.

rules: {
  password: () => [
    { required: true, message: 'Пароль обязателен', trigger: 'blur' },
    { min: 6, message: 'Минимум 6 символов', trigger: 'blur' }
  ]
}

Здесь password — это функция, которая возвращает массив правил, что позволяет изменять их при каждом обращении к валидации.

Валидация на основе других полей

Часто требуется валидировать поле в зависимости от значения другого поля. Для этого можно использовать кастомные валидаторы:

rules: {
  confirmPassword: [
    { required: true, message: 'Подтверждение пароля обязательно', trigger: 'blur' },
    { 
      validator: (rule, value, callback) => {
        if (value !== form.password) {
          callback(new Error('Пароли не совпадают'));
        } else {
          callback();
        }
      }, 
      trigger: 'blur' 
    }
  ]
}

Особенность динамического подхода в том, что значение form.password может изменяться, и валидатор всегда будет использовать актуальное состояние.

Реактивные правила с computed

При использовании Vue 3 и Composition API правила могут быть реактивными, что позволяет автоматически обновлять валидацию при изменении условий:

import { reactive, computed } from 'vue';

const form = reactive({
  type: 'user',
  email: ''
});

const rules = computed(() => ({
  email: [
    { required: form.type === 'user', message: 'Email обязателен', trigger: 'blur' },
    { type: 'email', message: 'Неверный формат email', trigger: 'blur' }
  ]
}));

Здесь поле email будет валидироваться как обязательное только для пользователей определённого типа. Любая смена form.type автоматически изменит правила.

Динамическая смена правил в процессе работы

Иногда правила нужно изменять по событию, например, при выборе опции в форме:

function onTypeChange(newType) {
  if (newType === 'admin') {
    formRules.email = [
      { required: true, message: 'Email обязателен для администратора', trigger: 'blur' },
      { type: 'email', message: 'Неверный формат email', trigger: 'blur' }
    ];
  } else {
    formRules.email = [
      { type: 'email', message: 'Неверный формат email', trigger: 'blur' }
    ];
  }
}

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

Использование validateField и clearValidate

При динамической смене правил важно корректно обновлять состояние валидации. Для этого применяются методы ElForm:

  • validateField(prop) — валидирует конкретное поле с учётом текущих правил.
  • clearValidate(prop?) — сбрасывает ошибки валидации для указанного поля или всей формы.

Пример:

formRef.clearValidate('email'); // сброс ошибок email перед применением новых правил
formRef.validateField('email'); // повторная проверка по новым правилам

Кастомизация с trigger

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

const dynamicRules = computed(() => {
  return {
    age: [
      { required: true, message: 'Возраст обязателен', trigger: 'change' },
      { validator: (rule, value, callback) => {
          if (value < 18) callback(new Error('Возраст должен быть 18+'));
          else callback();
        }, 
        trigger: form.isSubmit ? 'blur' : 'change'
      }
    ]
  }
});

Здесь триггер для проверки кастомного валидатора зависит от состояния формы.

Советы по производительности

  • Для больших форм лучше использовать computed или функции, возвращающие правила, чтобы избежать лишних перерасчетов.
  • Не стоит хранить реактивные массивы правил напрямую в data, если они зависят от состояния — это усложняет управление и может приводить к багам.
  • Кастомные валидаторы должны вызывать callback в любом случае, иначе валидация может “зависнуть”.

Итоговая структура динамических правил

  1. Статические правила для неизменяемых полей.
  2. Функции, возвращающие массив правил для полей с изменяющимися условиями.
  3. Кастомные валидаторы для зависимых проверок.
  4. Реактивные computed-правила для автоматического обновления.
  5. Методы validateField и clearValidate для управления состоянием.

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