SkateJS предоставляет мощный и гибкий механизм работы с распределением контента через слоты, что позволяет создавать высоко-компонентные веб-приложения с переиспользуемыми и изолированными элементами. Слоты обеспечивают разделение структуры компонента и передаваемого внутрь контента, позволяя реализовывать композицию компонентов без жесткой привязки к конкретной разметке.
В SkateJS слоты работают аналогично стандартным веб-компонентам с
<slot>. Любой элемент внутри компонента, который не
соответствует специфической точке распределения (слоту), автоматически
помещается в default slot. Простейший пример:
import { define, Component, h } from 'skatejs';
class Card extends Component {
renderCallback() {
return (
<div class="card">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
);
}
}
define('my-card', Card);
В этом примере определены три слота:
header — именованный слот для заголовка.footer — именованный слот для подвала.default slot — основной слот, куда попадет остальной
контент.Использование компонента может выглядеть так:
<my-card>
<h1 slot="header">Заголовок</h1>
<p>Основной контент карточки</p>
<button slot="footer">Нажми меня</button>
</my-card>
Элементы автоматически распределяются по слотам на основе атрибута
slot. Контент без указания имени помещается в default
slot.
Именованные слоты позволяют точно контролировать,
где конкретные части контента будут отображены. Атрибут
slot="имя" на элементе связывает его с соответствующим
слотом.
Default slot не требует имени. Любой элемент без
атрибута slot попадет именно туда. Если default slot
отсутствует, такие элементы игнорируются в распределении.
Важно помнить:
slot на компоненте может быть динамическим, что
позволяет менять расположение контента в зависимости от состояния.SkateJS позволяет изменять содержимое слотов программно, используя
children и assignedNodes():
class DynamicCard extends Component {
renderCallback() {
return (
<div>
<slot name="dynamic"></slot>
</div>
);
}
connectedCallback() {
super.connectedCallback();
const slot = this.shadowRoot.querySelector('slot[name="dynamic"]');
slot.addEventListener('slotchange', () => {
const nodes = slot.assignedNodes({ flatten: true });
console.log('Контент слота обновлен:', nodes);
});
}
}
Метод assignedNodes({ flatten: true }) возвращает массив
всех элементов, назначенных слоту, включая текстовые узлы и элементы
вложенных слотов.
SkateJS интегрирует слоты с реактивной системой компонентов. Изменение содержимого слота может автоматически вызывать обновление рендеринга или триггерить вычисляемые свойства:
class StatusCard extends Component {
static props = {
hasContent: { type: Boolean }
};
renderCallback() {
return (
<div>
<slot onSlotcha nge={() => this.hasContent = this.shadowRoot.querySelector('slot').assignedNodes().length > 0}></slot>
{this.hasContent ? <p>Контент доступен</p> : <p>Контент отсутствует</p>}
</div>
);
}
}
Событие slotchange обеспечивает реакцию компонента на
изменения распределенного контента.
В SkateJS слоты могут быть вложенными, что позволяет создавать сложные компоненты с несколькими уровнями распределения. Например, карточка с вкладками:
class TabPanel extends Component {
renderCallback() {
return (
<div class="tab-panel">
<nav>
<slot name="tabs"></slot>
</nav>
<section>
<slot name="content"></slot>
</section>
</div>
);
}
}
Элементы с slot="tabs" и slot="content"
могут содержать свои собственные слоты, позволяя организовать
многоуровневую структуру без потери контроля над содержимым.
slotchange для
динамических компонентов, чтобы отслеживать добавление или удаление
контента.Система слотов в SkateJS является ядром гибкой архитектуры веб-компонентов, обеспечивая мощные инструменты для композиции, переиспользования и динамического распределения контента. Правильное использование слотов позволяет создавать чистые, модульные и легко поддерживаемые компоненты, которые интегрируются в любые веб-приложения.