Слоты в Slim.js представляют собой механизм для распределения и вставки контента внутри компонентов. Они обеспечивают гибкую композицию компонентов, позволяя родительскому элементу определять, какой контент будет отображаться в дочернем компоненте. Слоты в Slim.js аналогичны концепции Web Components, но интегрированы в реактивную систему библиотеки.
Слот создается в шаблоне компонента с помощью тега
<slot>. Этот тег действует как маркер
позиции, в которую будет вставлен внешний контент:
class MyComponent extends Slim {
get template() {
return `
<div class="container">
<h2>Заголовок компонента</h2>
<slot></slot>
</div>
`;
}
}
customElements.define('my-component', MyComponent);
В примере <slot></slot> задает место, куда
будет помещен контент, переданный при использовании компонента:
<my-component>
<p>Это будет вставлено в слот</p>
</my-component>
Результатом рендеринга станет:
<div class="container">
<h2>Заголовок компонента</h2>
<p>Это будет вставлено в слот</p>
</div>
Slim.js поддерживает именованные слоты, что
позволяет вставлять различные фрагменты контента в конкретные области
компонента. Для этого используется атрибут name у
<slot> и соответствующий атрибут slot у
дочернего элемента:
class CardComponent extends Slim {
get template() {
return `
<div class="card">
<header><slot name="header"></slot></header>
<main><slot></slot></main>
<footer><slot name="footer"></slot></footer>
</div>
`;
}
}
customElements.define('card-component', CardComponent);
Использование компонента с именованными слотами:
<card-component>
<h1 slot="header">Заголовок карточки</h1>
<p>Основной контент карточки</p>
<p slot="footer">Подпись или примечание</p>
</card-component>
Slim.js корректно сопоставляет каждый элемент с соответствующим
слотом, оставляя неименованный слот для основного
контента, если атрибут slot не указан.
Слоты могут содержать контент по умолчанию, который отображается, если родительский компонент не передал никакой элемент.
class AlertComponent extends Slim {
get template() {
return `
<div class="alert">
<slot>Сообщение отсутствует</slot>
</div>
`;
}
}
customElements.define('alert-component', AlertComponent);
Использование без контента:
<alert-component></alert-component>
Выведет:
<div class="alert">
Сообщение отсутствует
</div>
Если же передать текст или элемент, дефолтный контент заменяется.
Slim.js обеспечивает реактивное обновление слотов. Любые изменения контента родительского компонента автоматически отражаются внутри слота без необходимости перерендеривания всего компонента. Это позволяет динамически управлять отображением и взаимодействием компонентов с разным контентом.
class DynamicList extends Slim {
get template() {
return `
<ul>
<slot></slot>
</ul>
`;
}
}
customElements.define('dynamic-list', DynamicList);
const list = document.querySelector('dynamic-list');
const item = document.createElement('li');
item.textContent = 'Новый элемент';
list.appendChild(item); // Слот автоматически обновится
Slim.js поддерживает вложенные слоты, что позволяет создавать сложные, многоуровневые компоненты с гибкой структурой. Вложенный слот может наследовать контент от родителя или использовать свой дефолтный контент.
class OuterComponent extends Slim {
get template() {
return `<div class="outer"><slot></slot></div>`;
}
}
class InnerComponent extends Slim {
get template() {
return `<div class="inner"><slot>Дефолтный текст внутреннего компонента</slot></div>`;
}
}
customElements.define('outer-component', OuterComponent);
customElements.define('inner-component', InnerComponent);
Использование:
<outer-component>
<inner-component></inner-component>
</outer-component>
Результат:
<div class="outer">
<div class="inner">Дефолтный текст внутреннего компонента</div>
</div>
slot совпадал с name слота; иначе контент
попадет в неименованный слот или останется
невидимым.Использование слотов в Slim.js обеспечивает высокий уровень гибкости, позволяя создавать модульные, переиспользуемые и динамичные интерфейсы.