Riot.js предоставляет мощный и гибкий механизм для организации компонентов и управления содержимым через слоты и проекцию контента. Эти возможности позволяют создавать переиспользуемые и настраиваемые компоненты, которые могут принимать внутренний контент, передаваемый извне.
Слот — это место внутри компонента, куда можно
передать произвольный контент из родительского компонента. По умолчанию
слоты обозначаются тегом <slot></slot> внутри
шаблона компонента:
<card>
<slot></slot>
</card>
При использовании компонента можно передавать содержимое внутрь слота:
<card>
<h1>Заголовок карточки</h1>
<p>Описание карточки</p>
</card>
В этом случае весь внутренний HTML окажется в месте, где расположен
<slot> внутри компонента card.
Для более сложных случаев можно использовать именованные
слоты, чтобы контролировать, куда именно попадет конкретный
фрагмент контента. Именованный слот задается через атрибут
name:
<card>
<slot name="header"></slot>
<slot name="body"></slot>
</card>
В родительском компоненте или шаблоне можно направлять контент в конкретный слот:
<card>
<h1 slot="header">Заголовок</h1>
<p slot="body">Основное содержание</p>
</card>
Именованные слоты особенно полезны, когда требуется гибко управлять структурой компонента и размещением нескольких независимых блоков контента.
Если слот не получает внешнего содержимого, можно задать контент по умолчанию, который будет отображаться:
<card>
<slot>Здесь будет стандартное содержимое</slot>
</card>
При отсутствии переданного контента <slot> выведет
текст внутри себя.
Для именованных слотов также поддерживается контент по умолчанию:
<slot name="footer">Подвал по умолчанию</slot>
Riot.js позволяет использовать динамический контент в слотах с помощью привязки данных. Например:
<card>
<slot>{ dynamicContent }</slot>
</card>
Здесь переменная dynamicContent из компонента-родителя
будет автоматически проецирована в слот. При изменении значения
dynamicContent обновление произойдет автоматически
благодаря реактивной системе Riot.js.
Проекция контента работает и для вложенных компонентов. Это значит, что один компонент может принимать слоты от родителя, а внутренние компоненты могут их использовать дальше:
<modal>
<card>
<h1 slot="header">Заголовок модального окна</h1>
<p slot="body">Текст внутри модалки</p>
</card>
</modal>
В таком случае компонент modal не должен заботиться о
внутреннем содержимом card, но слоты позволят корректно
разместить контент внутри всех вложенных компонентов.
Слоты поддерживают передачу атрибутов и событий из родителя внутрь компонента. Например, можно передать обработчики клика или кастомные свойства:
<card>
<button oncl ick={handleClick}>Нажать</button>
</card>
Событие onclick будет работать в контексте родительского
компонента. Это позволяет строить более интерактивные и модульные
интерфейсы.
Механизм слотов и проекции контента в Riot.js обеспечивает высокую модульность, повторное использование компонентов и контроль над структурой интерфейса без дублирования кода и усложнения архитектуры. Он является фундаментальной частью современного подхода к построению реактивных компонентов.