Riot.js — легковесный фреймворк для создания реактивных веб-интерфейсов. Структура приложения в Riot строится вокруг компонентов, которые объединяют разметку, логику и стили в единый модуль. Каждый компонент является самостоятельной единицей, что упрощает масштабирование и поддержку кода.
Компонент в Riot представляет собой файл с расширением
.riot. Основная структура файла включает три ключевых
блока:
Пример базового компонента:
<my-component>
<p>{ message }</p>
<script>
export default {
message: 'Привет, Riot!'
}
</script>
<style>
p {
color: #2c3e50;
font-size: 16px;
}
</style>
</my-component>
Выделение ключевых моментов:
export default.<style> автоматически применяются только
к текущему компоненту, исключая конфликты с другими частями
приложения.Riot.js поддерживает вложенные компоненты. Родительский компонент может импортировать дочерний и использовать его как HTML-тег:
<parent-component>
<child-component message="Привет из родителя"></child-component>
<script>
import ChildComponent from './child-component.riot';
export default {
components: { ChildComponent }
}
</script>
</parent-component>
Особенности работы с иерархией:
props).slots позволяет вставлять произвольное
содержимое внутрь дочернего компонента, сохраняя гибкость разметки.Riot обеспечивает автоматическое обновление DOM при изменении
состояния компонента. Любое свойство объекта, экспортированного через
export default, становится реактивным:
<counter>
<button oncl ick={ increment }>+</button>
<span>{ count }</span>
<script>
export default {
count: 0,
increment() {
this.count += 1;
}
}
</script>
</counter>
Ключевые моменты:
this, который
указывает на экземпляр компонента.Для больших приложений Riot предлагает централизованное управление
состоянием через store. Store представляет собой глобальный
объект с реактивными свойствами и методами для обновления данных:
// store.js
import { observable } from 'riot';
export const appStore = observable({
user: null,
setUser(user) {
this.user = user;
}
});
Использование store в компоненте:
<script>
import { appStore } from './store';
export default {
onMounted() {
this.user = appStore.user;
appStore.on('update', () => this.update());
}
}
</script>
Особенности работы со store:
Рекомендуемая структура проекта:
src/
├─ components/
│ ├─ header.riot
│ ├─ footer.riot
│ └─ counter.riot
├─ store/
│ └─ store.js
├─ pages/
│ ├─ home.riot
│ └─ about.riot
└─ main.js
Принципы организации:
main.js импортирует корневой компонент и
инициализирует приложение.Riot.js предоставляет методы жизненного цикла для управления состоянием и взаимодействием с DOM:
onBeforeMount() — вызывается перед рендером
компонента.onMounted() — после рендера, можно обращаться к
DOM.onBeforeUpdate() — перед обновлением реактивных
свойств.onUpdated() — после обновления DOM.onBeforeUnmount() — перед удалением компонента.onUnmounted() — после удаления, используется для
очистки ресурсов.Использование методов жизненного цикла позволяет оптимизировать производительность и корректно управлять ресурсами.
События в Riot.js делятся на локальные и глобальные. Локальные
события обрабатываются через атрибуты, например onclick,
oninput. Кастомные события создаются с помощью метода
trigger:
this.trigger('customEvent', { data: 123 });
Родительский компонент подписывается на событие через:
<child-component oncustomEv ent={ handleEvent }></child-component>
Такой подход обеспечивает слабую связанность компонентов и упрощает масштабирование приложения.
Структура Riot.js приложения строится вокруг компонента как основной единицы. Четкое разделение на шаблон, логику и стили, поддержка реактивного состояния, централизованного store, жизненного цикла и событий обеспечивает гибкость, масштабируемость и простоту поддержки кода. Правильная организация файлов и папок позволяет поддерживать порядок даже в крупных приложениях.