HTML Templates в Atomico позволяют создавать повторно используемые структуры разметки, которые могут быть внедрены в компонент с сохранением динамических данных и реактивности. Основная идея заключается в использовании шаблонов как абстракции для DOM, что упрощает управление сложными интерфейсами и делает компоненты более модульными.
Шаблон создаётся с помощью тега <template> и
функции html из Atomico:
import { html, c } from "atomico";
const cardTemplate = html`
<template>
<div class="card">
<h2></h2>
<p></p>
</div>
</template>
`;
В этом примере <template> не рендерится сразу на
страницу. Он хранит структуру, которую можно клонировать и вставлять в
компонент. Такой подход позволяет создавать множество экземпляров одной
структуры без повторного написания кода.
Для внедрения шаблона в компонент используется функция
use или прямое клонирование:
const Card = c(() => {
return html`
<host>
${cardTemplate.cloneNode(true)}
</host>
`;
});
Метод cloneNode(true) создаёт глубокую копию шаблона,
включая все вложенные элементы. После этого можно динамически вставлять
данные:
const card = cardTemplate.content.cloneNode(true);
card.querySelector("h2").textContent = "Заголовок";
card.querySelector("p").textContent = "Описание карточки";
Такой подход обеспечивает разделение структуры и данных, делая компоненты гибкими и легко тестируемыми.
Slots в Atomico используются для вставки пользовательского контента в заранее определённые места шаблона компонента. Они обеспечивают высокий уровень кастомизации без необходимости переписывать логику компонента.
const MyComponent = c(() => {
return html`
<host>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</host>
`;
});
<slot> без атрибута name является
дефолтным слотом, в который вставляется основной
контент.<slot name="..."> используется для именованных
областей, что позволяет распределять контент по конкретным частям
компонента.Пример использования:
<my-component>
<div slot="header">Заголовок компонента</div>
Основной текст
<div slot="footer">Подвал компонента</div>
</my-component>
В этом примере:
slot="header" попадёт в
<header>.<main>.slot="footer" попадёт в
<footer>.Atomico поддерживает динамическое управление слотами через реактивные данные:
import { useState, c, html } from "atomico";
const TabComponent = c(() => {
const [activeTab, setActiveTab] = useState("first");
return html`
<host>
<nav>
<button oncl ick=${() => setActiveTab("first")}>Первая вкладка</button>
<button oncl ick=${() => setActiveTab("second")}>Вторая вкладка</button>
</nav>
<section>
<slot name=${activeTab}></slot>
</section>
</host>
`;
});
Здесь <slot> динамически меняет имя, и содержимое
переключается в зависимости от состояния activeTab. Это
позволяет создавать интерактивные компоненты с несколькими
областями контента, не дублируя логику рендеринга.
Шаблоны и слоты часто используются совместно для построения многоразовых и настраиваемых компонентов:
const template = html`
<template>
<div class="panel">
<slot name="title"></slot>
<slot></slot>
</div>
</template>
`;
const Panel = c(() => {
const panel = template.content.cloneNode(true);
return html`<host>${panel}</host>`;
});
В этом примере:
template содержит слоты для заголовка и основного
содержимого.Panel клонирует шаблон, сохраняя возможность
вставки пользовательского контента через слоты.Шаблоны и слоты в Atomico образуют фундамент для построения сложных, настраиваемых компонентов с чистой архитектурой и высокой повторной используемостью кода.