Riot.js — легковесный фреймворк для построения реактивных интерфейсов, который использует компонентный подход и декларативную синтаксис. Формы в Riot.js можно создавать и управлять ими с высокой степенью интерактивности благодаря реактивным данным и привязке событий.
Каждая форма создается как отдельный компонент Riot.js. Компонент включает три ключевые секции:
Пример базового компонента формы:
<user-form>
<form onsub mit={submitForm}>
<label>
Имя:
<input type="text" name="name" bind={state.name}>
</label>
<label>
Email:
<input type="email" name="email" bind={state.email}>
</label>
<button type="submit">Отправить</button>
</form>
<p if={state.submitted}>Данные отправлены: {state.name}, {state.email}</p>
<script>
export default {
state: {
name: '',
email: '',
submitted: false
},
submitForm(event) {
event.preventDefault();
this.state.submitted = true;
}
}
</script>
<style>
form { display: flex; flex-direction: column; gap: 10px; }
label { font-weight: bold; }
input { padding: 5px; font-size: 14px; }
button { width: 100px; padding: 5px; }
</style>
</user-form>
В Riot.js состояние компонента (state) автоматически
отслеживается и обновляет интерфейс при изменениях. Для интерактивных
форм это особенно важно:
bind.if.Riot.js позволяет легко привязывать обработчики событий к элементам формы. Основные события:
onsubmit — отправка формы.oninput — ввод текста.onclick — нажатие кнопок.this.trigger.Пример динамической валидации поля email:
validateEmail() {
const email = this.state.email;
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
this.state.isValidEmail = re.test(email);
}
<input type="email" name="email" bind={state.email} onin put={validateEmail}>
<p if={!state.isValidEmail && state.email.length}>Некорректный email</p>
Riot.js поддерживает реактивные массивы для создания повторяющихся элементов формы. Например, список телефонов:
state: {
phones: ['']
},
addPhone() {
this.state.phones.push('');
},
removePhone(index) {
this.state.phones.splice(index, 1);
}
<div each={phone, index in state.phones}>
<input type="text" bind={state.phones[index]}>
<button type="button" oncl ick={() => removePhone(index)}>Удалить</button>
</div>
<button type="button" oncl ick={addPhone}>Добавить телефон</button>
Riot.js позволяет отправлять данные формы на сервер с использованием
fetch или других библиотек. Пример отправки данных
JSON:
async submitForm(event) {
event.preventDefault();
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: this.state.name, email: this.state.email })
});
if(response.ok) this.state.submitted = true;
}
Для сложных форм важно реализовать локальную и серверную валидацию:
Пример комбинированной валидации:
async submitForm(event) {
event.preventDefault();
this.state.errors = {};
if(!this.state.name) this.state.errors.name = 'Имя обязательно';
if(!this.state.email) this.state.errors.email = 'Email обязателен';
if(Object.keys(this.state.errors).length) return;
try {
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: this.state.name, email: this.state.email })
});
if(!response.ok) throw new Error('Ошибка сервера');
this.state.submitted = true;
} catch(e) {
this.state.errors.server = e.message;
}
}
<p if={state.errors.name}>{state.errors.name}</p>
<p if={state.errors.email}>{state.errors.email}</p>
<p if={state.errors.server}>{state.errors.server}</p>
Для больших приложений формы можно разделять на подкомпоненты:
Такой подход улучшает читаемость кода, повторное использование и поддержку.
Интерактивные формы в Riot.js строятся на сочетании:
state) для мгновенного
обновления интерфейса.bind) и
условной визуализации (if).Этот комплексный подход позволяет создавать сложные формы с высокой интерактивностью, минимальными усилиями и чистой архитектурой.