Stencil предоставляет мощный инструмент для создания веб-компонентов с поддержкой декларативного программирования и реактивности. Одной из важнейших задач при работе с компонентами является валидация данных формы. В этой главе рассмотрим способы реализации валидации форм в приложениях, построенных на Stencil.
Валидация формы — это процесс проверки данных, введённых пользователем, с целью убедиться в их корректности перед отправкой. В Stencil валидация может быть реализована на уровне компонента, при этом можно воспользоваться встроенными механизмами или добавить собственные.
В случае с Stencil валидация часто реализуется с использованием декларативных атрибутов, реактивных переменных и событий. Важным моментом является то, что Stencil позволяет интегрировать валидацию как на уровне пользовательского интерфейса, так и на уровне бизнес-логики, что даёт гибкость в реализации.
Сбор данных формы На первом этапе необходимо
собрать данные, введённые пользователем. В Stencil это можно сделать
через двустороннее связывание данных с использованием
@Prop() и @State().
Применение проверок После того как данные формы собраны, они проверяются на соответствие заданным правилам. Это можно реализовать как через встроенные методы HTML-форм, так и через кастомные проверки, написанные вручную.
Предоставление обратной связи пользователю На последнем этапе важно предоставить пользователю информацию о том, что он сделал что-то неправильно, например, подсветив поля ошибки или выведя текст сообщения.
Stencil поддерживает все стандартные атрибуты валидации HTML5, такие
как required, minlength,
maxlength, pattern, и другие. Эти атрибуты
могут быть добавлены к элементам формы, таким как
<input>, <select>,
<textarea>, для автоматической проверки данных при
отправке формы.
<form>
<label>
Email:
<input type="email" required />
</label>
<button type="submit">Отправить</button>
</form>
Пример выше показывает, как можно использовать встроенную валидацию для поля email. Если пользователь не введёт корректный email, форма не будет отправлена, и браузер автоматически отобразит сообщение об ошибке.
Для более сложных случаев, когда нужно выполнить дополнительные
проверки, Stencil предлагает использовать реактивное связывание данных.
С помощью @State() можно отслеживать состояние полей и
производить валидацию в реальном времени.
Пример использования реактивной валидации:
import { Component, h, State } from '@stencil/core';
@Component({
tag: 'custom-form',
styleUrl: 'custom-form.css',
shadow: true
})
export class CustomForm {
@State() email: string = '';
@State() emailError: string = '';
validateEmail() {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
this.emailError = emailRegex.test(this.email) ? '' : 'Некорректный email';
}
handleSubmit(event: Event) {
event.preventDefault();
this.validateEmail();
if (!this.emailError) {
// Отправить форму
}
}
render() {
return (
<form onSub mit={(e) => this.handleSubmit(e)}>
<label>
Email:
<input
type="email"
value={this.email}
onIn put={(e) => (this.email = (e.target as HTMLInputElement).value)}
onB lur={() => this.validateEmail()}
/>
</label>
{this.emailError && <p class="error">{this.emailError}</p>}
<button type="submit">Отправить</button>
</form>
);
}
}
В этом примере:
email,
который отслеживает значение поля.onBlur) запускается валидация.Когда форма состоит из нескольких полей, важно контролировать состояние всех этих полей. Stencil предоставляет удобные способы для этого. Каждое поле может иметь свою собственную логику валидации, а затем можно собрать все результаты в одном месте.
Пример валидации формы с несколькими полями:
@Component({
tag: 'multi-field-form',
styleUrl: 'multi-field-form.css',
shadow: true
})
export class MultiFieldForm {
@State() name: string = '';
@State() email: string = '';
@State() nameError: string = '';
@State() emailError: string = '';
validateName() {
this.nameError = this.name ? '' : 'Имя обязательно для заполнения';
}
validateEmail() {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
this.emailError = emailRegex.test(this.email) ? '' : 'Некорректный email';
}
handleSubmit(event: Event) {
event.preventDefault();
this.validateName();
this.validateEmail();
if (!this.nameError && !this.emailError) {
// Отправить форму
}
}
render() {
return (
<form onSub mit={(e) => this.handleSubmit(e)}>
<label>
Имя:
<input
type="text"
value={this.name}
onIn put={(e) => (this.name = (e.target as HTMLInputElement).value)}
onB lur={() => this.validateName()}
/>
</label>
{this.nameError && <p class="error">{this.nameError}</p>}
<label>
Email:
<input
type="email"
value={this.email}
onIn put={(e) => (this.email = (e.target as HTMLInputElement).value)}
onB lur={() => this.validateEmail()}
/>
</label>
{this.emailError && <p class="error">{this.emailError}</p>}
<button type="submit">Отправить</button>
</form>
);
}
}
Здесь форма проверяет два поля: имя и email. Каждое поле имеет свою собственную логику валидации, и все ошибки отображаются в виде сообщений рядом с полями.
В некоторых случаях требуется выполнить асинхронную валидацию данных, например, для проверки уникальности email или имени пользователя. Для этого можно использовать асинхронные функции, которые будут вызываться при изменении значения поля или при отправке формы.
Пример асинхронной валидации:
@Component({
tag: 'async-validation-form',
styleUrl: 'async-validation-form.css',
shadow: true
})
export class AsyncValidationForm {
@State() email: string = '';
@State() emailError: string = '';
async validateEmail() {
const emailExists = await this.checkEmailAvailability(this.email);
this.emailError = emailExists ? 'Этот email уже занят' : '';
}
async checkEmailAvailability(email: string): Promise<boolean> {
// Эмуляция асинхронного запроса
const existingEmails = ['test@example.com', 'user@example.com'];
return existingEmails.includes(email);
}
handleSubmit(event: Event) {
event.preventDefault();
this.validateEmail();
if (!this.emailError) {
// Отправить форму
}
}
render() {
return (
<form onSub mit={(e) => this.handleSubmit(e)}>
<label>
Email:
<input
type="email"
value={this.email}
onIn put={(e) => (this.email = (e.target as HTMLInputElement).value)}
onB lur={() => this.validateEmail()}
/>
</label>
{this.emailError && <p class="error">{this.emailError}</p>}
<button type="submit">Отправить</button>
</form>
);
}
}
В этом примере используется асинхронная функция для проверки доступности email в базе данных (эмулированной с помощью массива). Этот подход полезен при работе с внешними API и при необходимости выполнения длительных операций.
Важно не только выполнять валидацию, но и предоставить пользователю понятные и информативные сообщения об ошибках. В Stencil можно динамически отображать ошибки с помощью условных операторов и состояния компонентов.
{this.emailError && <p class="error">{this.emailError}</p>}
Такой подход позволяет гибко управлять отображением ошибок и делать интерфейс более дружелюбным для пользователей.
Вали