В Riot.js компоненты строятся вокруг структуры с шаблоном, логикой и состоянием, а ключевым механизмом передачи данных между ними являются атрибуты и свойства. Понимание их работы позволяет создавать гибкие и переиспользуемые элементы интерфейса.
Атрибуты в Riot.js — это способ передачи данных в компонент при его
создании. Они задаются аналогично HTML-атрибутам и доступны внутри
компонента через объект props.
Пример использования атрибутов:
<user-card name="Иван" age="30"></user-card>
<script type="riot">
<user-card>
<p>{props.name} — {props.age} лет</p>
</user-card>
</script>
Здесь name и age передаются как атрибуты и
автоматически доступны через props. Riot.js выполняет
преобразование типов, но значения, переданные через
HTML, по умолчанию интерпретируются как строки. Для передачи чисел,
булевых значений или объектов можно использовать инлайновый
JavaScript:
<user-card age={30} active={true}></user-card>
В этом случае props.age будет числом, а
props.active — булевым значением.
Компоненты могут определять значения по умолчанию
для атрибутов через объект props в методе
onBeforeMount или при инициализации:
this.props = {
name: this.props.name || 'Неизвестный',
age: this.props.age || 0
}
Если атрибут изменяется извне после создания компонента, Riot
автоматически обновляет отображение, так как props являются
реактивными. Важно помнить, что изменения примитивных
значений (строк, чисел, булевых) происходят только при присваивании
новых значений, тогда как для объектов и массивов изменения внутри
структуры не вызывают автоматического рендеринга, если не используется
метод this.update().
Свойства (state или this.*) — это данные,
которые определяются и управляются внутри самого компонента. Они
отделены от атрибутов и используются для внутренней логики и управления
состоянием.
<counter>
<button oncl ick={increment}>+</button>
<p>Счетчик: {count}</p>
<script>
this.count = 0
increment() {
this.count++
this.update()
}
</script>
</counter>
Ключевые моменты:
this.count — внутреннее состояние компонента.this.update() — метод, который обновляет шаблон при
изменении состояния.Для передачи и синхронизации данных между родительским и дочерним компонентами используется двустороннее связывание или методы обратного вызова:
<parent>
<child value={childValue} onUPDATE={handleUpdate}></child>
<script>
this.childValue = 'Начальное значение'
handleUpdate(newValue) {
this.childValue = newValue
this.update()
}
</script>
</parent>
value — атрибут, передаваемый в дочерний
компонент.onupdate — функция, которую дочерний компонент вызывает
при изменении данных.Такой подход позволяет реализовать контролируемые компоненты, где родитель управляет состоянием, а дочерний компонент лишь отображает данные и уведомляет о событиях.
Для упрощения доступа к атрибутам часто используется
деструктуризация объекта props:
const { name, age } = this.props
Это делает код более читаемым, особенно при работе с компонентами, принимающими большое количество атрибутов.
Riot.js позволяет передавать сложные структуры данных:
<user-list users={usersArray}></user-list>
В компоненте:
this.props.users.forEach(user => console.log(user.name))
Изменение элементов массива или полей объекта требует вызова
this.update() для корректного рендеринга.
Атрибуты могут вычисляться на лету через выражения внутри фигурных скобок:
<badge label={isActive ? 'Активен' : 'Неактивен'}></badge>
Это позволяет создавать гибкие компоненты, реагирующие на изменения состояния без дополнительных методов.
| Параметр | Атрибуты (props) |
Свойства (state) |
|---|---|---|
| Источник | Передаются родителем при рендере | Определяются внутри компонента |
| Доступ | this.props |
this.* |
| Реактивность | Да, при изменении внешнего значения | Да, при вызове this.update() |
| Назначение | Входные данные компонента | Внутреннее состояние и логика |
| Доступ извне | Да, через родительский компонент | Нет, изолировано |
Атрибуты и свойства — фундамент для построения динамических, реактивных компонентов в Riot.js. Правильное их использование обеспечивает чистую архитектуру и легкую поддержку больших приложений.