Atomico — это современная библиотека для создания веб-компонентов на JavaScript с реактивным подходом. Основная идея заключается в использовании функционального компонента и реактивных сигналов для управления состоянием, что позволяет создавать гибкие и масштабируемые интерфейсы без необходимости подключения сторонних фреймворков.
Каждый компонент в Atomico создается через функцию c,
которая принимает функцию компонента и объект
опциональных настроек:
import { c, html, useState } from "atomico";
function MyComponent() {
const [count, setCount] = useState(0);
return html`
<button oncl ick=${() => setCount(count + 1)}>
Счётчик: ${count}
</button>
`;
}
customElements.define("my-component", c(MyComponent));
c(Component) — превращает обычную функцию в
веб-компонент.html — шаблонизатор, похожий на lit-html,
для декларативного описания разметки.useState — реактивный сигнал для управления локальным
состоянием компонента.Сигналы — ключевой механизм реактивности в Atomico. Они позволяют автоматически отслеживать изменения значений и перерисовывать интерфейс при их обновлении.
import { useSignal } from "atomico";
function Timer() {
const time = useSignal(0);
setInterval(() => {
time.value += 1;
}, 1000);
return html`<p>Время: ${time}</p>`;
}
Особенности сигналов:
useSignal(initialValue)..value автоматически инициирует
обновление шаблона.const items = useSignal([1, 2, 3]);
const doubled = () => items.value.map(x => x * 2);
Atomico позволяет описывать свойства компонентов с помощью функции
props внутри объекта c(Component, options).
Это обеспечивает строгую типизацию и реактивное обновление при изменении
внешних данных.
MyComponent.props = {
name: String,
age: Number
};
function MyComponent({ name, age }) {
return html`<p>${name} — ${age} лет</p>`;
}
String,
Number, Boolean, Array,
Object.Atomico поддерживает стандартные веб-слоты для передачи контента внутрь компонента. Слоты создаются с помощью обычного HTML и могут быть именованными.
function Card({ title }) {
return html`
<div class="card">
<h2>${title}</h2>
<slot></slot>
</div>
`;
}
<slot></slot> — универсальный слот для
вложенного контента.<slot name="footer"></slot> — именованный
слот.<div slot="footer">Подвал</div>.Atomico предоставляет несколько хуков жизненного цикла для работы с эффектами и реактивностью:
useEffect(callback, dependencies) — выполняется при
изменении зависимостей.useUpdate(callback) — вызывается после каждого
обновления компонента.useUnmount(callback) — вызывается при удалении
компонента из DOM.Пример использования useEffect:
function Clock() {
const time = useSignal(new Date().toLocaleTimeString());
useEffect(() => {
const timer = setInterval(() => {
time.value = new Date().toLocaleTimeString();
}, 1000);
return () => clearInterval(timer);
}, []);
return html`<p>${time}</p>`;
}
Atomico позволяет инкапсулировать стили внутри компонентов с помощью
тега css:
import { css } from "atomico";
const style = css`
.button {
background: blue;
color: white;
border: none;
padding: 10px;
border-radius: 4px;
}
`;
function StyledButton() {
return html`
<button class="button">Нажми меня</button>
${style}
`;
}
Компоненты Atomico легко комбинировать друг с другом. Вложенные компоненты могут принимать свойства и сигналы:
function App() {
const count = useSignal(0);
return html`
<my-counter .count=${count}></my-counter>
<button oncl ick=${() => count.value += 1}>Увеличить</button>
`;
}
function MyCounter({ count }) {
return html`<p>Счёт: ${count}</p>`;
}
Atomico использует стандартные DOM-события, а также позволяет
создавать кастомные события через
dispatchEvent:
function CustomButton() {
const handleClick = (event) => {
event.target.dispatchEvent(
new CustomEvent("increment", { bubbles: true, composed: true })
);
};
return html`<button oncl ick=${handleClick}>+</button>`;
}
onincrement.bubbles: true позволяет событию всплывать по
DOM-дереву.composed: true делает событие доступным за пределами
Shadow DOM.Списки и массивы в Atomico можно отрисовывать реактивно с помощью
обычного метода .map():
const items = useSignal(["яблоко", "банан", "вишня"]);
function List() {
return html`
<ul>
${items.value.map(item => html`<li>${item}</li>`)}
</ul>
`;
}
items.value.push("груша")
автоматически обновляет DOM.useEffect с зависимостями позволяет избегать лишних
вычислений.Atomico объединяет простоту функциональных компонентов с мощью реактивной архитектуры, предоставляя чистый, модульный и высокопроизводительный способ создания современных веб-компонентов.