Подключение к DOM

Atomico — это библиотека для создания веб-компонентов на JavaScript с реактивным подходом. Взаимодействие с DOM в Atomico построено вокруг функции c, которая позволяет описывать компоненты декларативно, и специальных хуков для управления состоянием и эффектами.


Создание и подключение компонента к DOM

В Atomico компонент определяется как функция, возвращающая структуру DOM через JSX-подобный синтаксис. Например:

import { c, useState } from "atomico";

function Counter() {
    const [count, setCount] = useState(0);

    return (
        
            
        
    );
}

customElements.define("x-counter", c(Counter));

Ключевые моменты:

  • — корневой элемент компонента, аналог Shadow DOM.
  • c(Component) возвращает класс веб-компонента, который можно регистрировать через customElements.define.
  • События (onClick) и реактивные состояния (useState) управляют содержимым компонента без прямого доступа к DOM.

Хуки для работы с DOM

Atomico предоставляет несколько хуков, которые упрощают работу с элементами и их состоянием.

useRef

Используется для прямого доступа к DOM-элементу:

import { c, useRef } from "atomico";

function FocusInput() {
    const inputRef = useRef();

    return (
        
            
            
        
    );
}

customElements.define("x-focus-input", c(FocusInput));

Особенности useRef:

  • Сохраняет ссылку на элемент между рендерами.
  • Не вызывает повторный рендер при изменении current.

useEffect

Применяется для управления побочными эффектами, например, для изменения DOM после рендера:

import { c, useEffect, useRef } from "atomico";

function Highlight() {
    const divRef = useRef();

    useEffect(() => {
        divRef.current.style.backgroundColor = "yellow";
    }, []);

    return 
Подсвеченный блок
; } customElements.define("x-highlight", c(Highlight));

Принципы работы:

  • Хук вызывается после рендера.
  • Второй аргумент ([]) задаёт зависимости: пустой массив — выполняется один раз после монтирования.

Слот и Shadow DOM

Компоненты Atomico по умолчанию используют Shadow DOM. Для вставки внешнего содержимого применяется :

function Card() {
    return (
        
            
); } customElements.define("x-card", c(Card));
  • Содержимое, переданное внутрь , автоматически попадёт в .
  • Можно создавать именованные слоты для более сложных шаблонов.

Атрибуты и свойства

Для взаимодействия с DOM через свойства и атрибуты компонента используют props:

function Badge({ text }) {
    return {text};
}

customElements.define("x-badge", c(Badge));
  • Любое изменение свойства автоматически обновляет DOM.
  • Свойства можно связать с атрибутами HTML:
< x-badge text="Новый текст" >

Работа с событиями

Atomico позволяет подписываться на события прямо в JSX:

function Toggle() {
    const [active, setActive] = useState(false);

    return (
        
            
        
    );
}

customElements.define("x-toggle", c(Toggle));
  • События можно делегировать на вложенные элементы.
  • Для передачи события наружу используется dispatchEvent:
host.dispatchEvent(new CustomEvent("toggle", { detail: active }));

Манипуляции с DOM напрямую

Хотя Atomico минимизирует прямое вмешательство в DOM, иногда это необходимо:

import { c, useEffect, useRef } from "atomico";

function ScrollToTop() {
    const container = useRef();

    useEffect(() => {
        container.current.scrollTop = 0;
    }, []);

    return (
        
            
Длинный контент...
); } customElements.define("x-scroll-to-top", c(ScrollToTop));
  • Использование ref и useEffect позволяет безопасно изменять DOM после рендера.
  • Рекомендуется избегать прямого изменения состояния компонентов внутри эффектов, чтобы не вызывать бесконечные рендеры.

Стилизация элементов

Стили применяются через стандартные CSS или через Shadow DOM:

function StyledBox() {
    return (
        
            
            
); } customElements.define("x-styled-box", c(StyledBox));
  • Стиль внутри изолирован компонентом.
  • Можно использовать CSS-переменные для передачи данных между компонентами.

Динамическое обновление DOM

Atomico обновляет только изменённые узлы благодаря реактивности:

function List({ items }) {
    return (
        
            
    {items.map(item =>
  • {item}
  • )}
); } customElements.define("x-list", c(List));
  • При изменении items изменятся только новые или удалённые
  • .
  • Это снижает нагрузку на DOM и повышает производительность.