В библиотеке Naive UI для работы с формами
используется компонент n-form, который позволяет управлять
состоянием полей и проверять их корректность с помощью системы
валидаторов. Помимо встроенных правил
(required, type, min,
max и др.), часто возникает необходимость создавать
кастомные правила валидации, отвечающие специфическим
требованиям приложения.
Кастомные правила создаются через объект rules для
каждого поля формы. В Naive UI каждое правило описывается как объект со
следующими ключевыми свойствами:
required — boolean, определяет обязательность
поля.trigger — событие, при котором происходит проверка
(blur, input или change).validator — функция, реализующая кастомную
проверку.Пример структуры правила с кастомным валидатором:
const rules = {
username: [
{
required: true,
trigger: 'blur',
validator: (rule, value) => {
if (!/^[a-zA-Z0-9_]{4,16}$/.test(value)) {
return new Error('Имя пользователя должно содержать 4-16 символов и состоять из латиницы, цифр или подчеркивания');
}
return true;
}
}
]
}
Функция validator может быть синхронной
или асинхронной. Синхронный валидатор возвращает
true при успешной проверке или Error при
ошибке. Асинхронный валидатор возвращает Promise, что
позволяет выполнять проверки, требующие обращения к серверу.
Пример асинхронного валидатора для проверки уникальности email:
const rules = {
email: [
{
required: true,
trigger: 'blur',
validator: async (rule, value) => {
const response = await fetch(`/api/check-email?email=${value}`);
const data = await response.json();
if (!data.available) {
throw new Error('Этот email уже зарегистрирован');
}
return true;
}
}
]
}
Для одного поля можно задавать несколько правил, которые будут проверяться последовательно. Например, поле пароля может проверяться на минимальную длину и наличие хотя бы одной цифры:
const rules = {
password: [
{
required: true,
trigger: 'blur',
validator: (rule, value) => {
if (value.length < 8) {
return new Error('Пароль должен быть не менее 8 символов');
}
return true;
}
},
{
trigger: 'blur',
validator: (rule, value) => {
if (!/\d/.test(value)) {
return new Error('Пароль должен содержать хотя бы одну цифру');
}
return true;
}
}
]
}
Функция валидатора получает следующие аргументы:
rule — объект текущего правила, включая все его
свойства (required, trigger,
message и т.д.).value — текущее значение поля, которое
проверяется.callback — устаревший способ возвращения ошибки, сейчас
предпочтительно использовать return или
throw Error.trigger задает событие, на котором будет выполняться
проверка. В Naive UI доступны следующие варианты:
blur — проверка при потере фокуса поля.input — проверка при каждом вводе символа.change — проверка при изменении значения (например, для
sel ect или checkbox).Применение правильного триггера позволяет оптимизировать пользовательский опыт, не вызывая постоянные уведомления об ошибках при каждом вводе.
required, min,
max и другими стандартными проверками.<template>
<n-form :model="form" :rules="rules" ref="formRef">
<n-form-item label="Имя пользователя" path="username">
<n-input v-model:value="form.username" />
</n-form-item>
<n-form-item label="Email" path="email">
<n-input v-model:value="form.email" />
</n-form-item>
<n-form-item label="Пароль" path="password">
<n-input type="password" v-model:value="form.password" />
</n-form-item>
<n-button @click="submitForm">Отправить</n-button>
</n-form>
</template>
<script setup>
import { ref } fr om 'vue'
import { NForm, NFormItem, NInput, NButton } from 'naive-ui'
const formRef = ref(null)
const form = ref({
username: '',
email: '',
password: ''
})
const rules = {
username: [
{
required: true,
trigger: 'blur',
validator: (rule, value) => /^[a-zA-Z0-9_]{4,16}$/.test(value) || new Error('Имя пользователя должно быть 4-16 символов')
}
],
email: [
{
required: true,
trigger: 'blur',
validator: async (rule, value) => {
const response = await fetch(`/api/check-email?email=${value}`)
const data = await response.json()
if (!data.available) throw new Error('Этот email уже зарегистрирован')
return true
}
}
],
password: [
{
required: true,
trigger: 'blur',
validator: (rule, value) => value.length >= 8 || new Error('Пароль должен быть не менее 8 символов')
},
{
trigger: 'blur',
validator: (rule, value) => /\d/.test(value) || new Error('Пароль должен содержать хотя бы одну цифру')
}
]
}
const submitForm = () => {
formRef.value.validate().then(() => {
console.log('Форма валидна', form.value)
}).catch((errors) => {
console.log('Ошибки валидации', errors)
})
}
</script>
В этом примере каждое поле имеет свои кастомные правила, включая асинхронную проверку email и последовательные проверки пароля, что демонстрирует гибкость Naive UI при построении форм с сложной логикой валидации.
Ключевой момент — использование функции validator,
которая может быть как синхронной, так и асинхронной, а также
возможность комбинировать несколько правил на одном поле с различными
триггерами, обеспечивая точный и удобный контроль за корректностью
данных.