Асинхронная валидация в Element Plus позволяет выполнять проверки данных формы не только на стороне клиента, но и обращаться к серверу или выполнять сложные вычисления перед подтверждением корректности ввода. Это особенно важно для проверок, которые не могут быть выполнены мгновенно, например, проверка уникальности имени пользователя или валидность токена.
async validatorОсновной инструмент для асинхронной валидации — это функция
validator, возвращающая Promise. В отличие от
синхронной проверки, где возвращается true или
false, асинхронная функция использует промис, который
разрешается при успешной валидации или отклоняется с сообщением об
ошибке.
Пример:
import { reactive } from 'vue';
const rules = reactive({
username: [
{
required: true,
message: 'Имя пользователя обязательно',
trigger: 'blur'
},
{
validator: async (rule, value) => {
if (!value) return Promise.resolve();
const response = await fetch(`/api/check-username?username=${value}`);
const data = await response.json();
if (data.exists) {
return Promise.reject('Имя пользователя уже занято');
}
return Promise.resolve();
},
trigger: 'blur'
}
]
});
Ключевые моменты:
validator всегда принимает два аргумента:
rule и value.Promise.Promise.reject('сообщение') прерывает валидацию и
выводит сообщение об ошибке.Promise.resolve() подтверждает корректность
значения.Часто требуется объединять базовые проверки (например, обязательное поле) с асинхронной проверкой. Element Plus поддерживает последовательное выполнение правил. Сначала выполняются синхронные проверки, затем асинхронные.
Пример комбинирования:
const rules = reactive({
email: [
{
required: true,
message: 'Email обязателен',
trigger: 'blur'
},
{
type: 'email',
message: 'Некорректный формат email',
trigger: ['blur', 'change']
},
{
validator: async (rule, value) => {
const res = await fetch(`/api/check-email?email=${value}`);
const data = await res.json();
if (data.exists) {
return Promise.reject('Email уже зарегистрирован');
}
return Promise.resolve();
},
trigger: 'blur'
}
]
});
Асинхронные правила срабатывают при вызове метода
validate формы. Метод возвращает промис, который можно
использовать для выполнения дальнейших действий после успешной валидации
или обработки ошибок.
Пример:
import { ref } from 'vue';
const formRef = ref(null);
const formData = reactive({ username: '', email: '' });
async function submitForm() {
try {
await formRef.value.validate();
console.log('Форма валидна, можно отправлять данные на сервер');
} catch (err) {
console.log('Ошибка валидации:', err);
}
}
Особенности:
validate проверяет все поля формы, включая
асинхронные.resetFields() позволяет очистить ошибки и вернуть
форму к исходному состоянию.Для улучшения производительности при проверках, обращающихся к серверу, полезно использовать debounce, чтобы запрос выполнялся не на каждое изменение, а через заданный интервал после последнего ввода.
Пример с использованием lodash.debounce:
import debounce from 'lodash/debounce';
const checkUsername = debounce(async (value) => {
const response = await fetch(`/api/check-username?username=${value}`);
const data = await response.json();
if (data.exists) throw new Error('Имя пользователя уже занято');
}, 500);
const rules = reactive({
username: [
{
validator: async (rule, value) => {
if (!value) return Promise.resolve();
try {
await checkUsername(value);
} catch (err) {
return Promise.reject(err.message);
}
},
trigger: 'blur'
}
]
});
Преимущества:
При динамически создаваемых полях (например, добавляемые элементы массива) важно создавать уникальные правила для каждого поля, иначе все элементы будут использовать один и тот же промис и состояние ошибок.
Пример с массивом пользователей:
const users = reactive([
{ name: '', rules: [] },
]);
function addUser() {
users.push({
name: '',
rules: [
{
validator: async (rule, value) => {
const res = await fetch(`/api/check-username?username=${value}`);
const data = await res.json();
if (data.exists) return Promise.reject('Имя пользователя уже занято');
return Promise.resolve();
},
trigger: 'blur'
}
]
});
}
validator.Асинхронная валидация в Element Plus обеспечивает гибкость и точность проверки данных, позволяя сочетать клиентские и серверные проверки в одной форме. Это критически важно для современных приложений с динамическими формами и высокими требованиями к корректности пользовательского ввода.