Vest построена вокруг декларативного описания правил валидации и выполнения тестов по требованию, что делает её естественной средой для реализации ленивой (lazy) валидации. Ленивый подход здесь означает выполнение проверок не для всего набора данных целиком, а строго для тех полей, которые действительно требуют проверки в текущем контексте взаимодействия.
В основе ленивой валидации лежит идея отложенного выполнения тестов. В классическом сценарии формы валидации проверяются полностью при каждом изменении данных. Такой подход быстро становится узким местом при росте формы и усложнении правил.
Ленивая стратегия в Vest выражается через:
В отличие от агрессивной валидации, где вся схема пересчитывается целиком, ленивый режим работает по принципу минимального необходимого вычисления.
Vest организует валидацию через «сьюты» и «тесты». Каждый тест привязан к конкретному полю или условию.
Ленивая валидация опирается на внутреннее состояние выполнения:
import { suite, test, enforce } from 'vest';
const validation = (data) =>
suite('form', () => {
test('username', 'Имя обязательно', () => {
enforce(data.username).isNotEmpty();
});
test('email', 'Некорректный email', () => {
enforce(data.email).matches(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
});
});
В таком виде библиотека уже способна выполнять частичную проверку, но ленивость проявляется только при управлении запуском сьюта и его полей.
Ленивая валидация в Vest обычно строится вокруг событийной модели:
validation({ username: 'alex' }).getErrors('username');
В этом случае выполняются только тесты, связанные с
username, остальные правила остаются неактивными.
Часто применяется стратегия «не валидировать до взаимодействия»:
let touched = {};
const onCha nge = (field, value) => {
touched[field] = true;
validation({ [field]: value })
.getErrors(field);
};
Такой подход снижает нагрузку на каждое изменение и делает проверку строго контекстной.
Ключевой элемент ленивой валидации — состояние «затронутости» (touched). Vest не навязывает его напрямую, но архитектурно предполагает его использование на уровне приложения.
Ленивая валидация активируется обычно только после перехода поля в состояние touched.
const state = {
touched: {},
};
function setValue(field, value) {
state.touched[field] = true;
const result = validation({ [field]: value });
if (state.touched[field]) {
return result.getErrors(field);
}
}
Одной из ключевых оптимизаций ленивой валидации является кеширование.
Vest способен повторно использовать результаты предыдущих тестов, если:
Это позволяет избегать повторного выполнения дорогостоящих проверок.
Если email уже был проверен и значение не
изменилось:
validation({ email: 'test@mail.com' }).getErrors('email');
повторный вызов не приведёт к повторному выполнению regex-проверки, если состояние сьюта не изменилось.
В сложных формах поля часто зависят друг от друга. Ленивая валидация должна учитывать такие зависимости, чтобы не запускать лишние тесты.
test('passwordConfirmation', 'Пароли не совпадают', () => {
enforce(data.passwordConfirmation).equals(data.password);
});
При изменении password необходимо пересчитать только
зависимые тесты, а не всю форму целиком.
Ленивая стратегия здесь включает:
Одним из ключевых механизмов ленивости является возможность запускать валидацию на уровне одного поля.
validation(data).getErrors('email');
Это эквивалент «точечного» запуска тестов:
email;Vest поддерживает условное выполнение тестов, что усиливает ленивую стратегию.
test('age', 'Недопустимый возраст', () => {
if (!data.age) return;
enforce(data.age).greaterThan(18);
});
Такие конструкции позволяют полностью пропускать тесты при отсутствии условий.
В реальных интерфейсах ленивый подход применяется в следующих сценариях:
На каждом шаге активируется только часть схемы:
const step1 = validation({ username, email }).getErrors();
const step2 = validation({ password }).getErrors();
Это естественная форма ленивой валидации, где остальная логика «спит» до перехода на следующий шаг.
Ленивая валидация особенно важна при асинхронных проверках:
test('email', 'Email уже используется', async () => {
const exists = await api.checkEmail(data.email);
enforce(exists).equals(false);
});
В ленивом режиме такой тест выполняется только при изменении email, а не при любом изменении формы.
Контроль момента пересчёта является ядром ленивой стратегии.
Основные подходы:
const onB lur = () => {
validation(data).getErrors();
};
Ленивая валидация снижает нагрузку за счёт:
В сложных формах это превращается в линейную зависимость от количества изменённых полей, а не от общего размера формы.