Vite и быстрая разработка

Atomico — это библиотека для создания веб-компонентов на JavaScript с реактивной моделью данных. Компоненты в Atomico строятся вокруг функции component, которая возвращает JSX-разметку и позволяет описывать логику компонента через хуки и свойства.

import { component, useState, html } from "atomico";

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

    return html`
        <button oncl ick=${() => setCount(count + 1)}>
            Счетчик: ${count}
        </button>
    `;
});

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

  • component создаёт кастомный элемент, который можно использовать как стандартный HTML-тег.
  • useState обеспечивает реактивное состояние, аналогично React.
  • html используется для описания разметки с поддержкой выражений внутри ${}.

Свойства и атрибуты компонентов

Компоненты Atomico могут принимать свойства (props), которые объявляются через статическое свойство props. Типизация свойств может быть описана через стандартные конструкторы JavaScript или через type и default.

const Button = component(() => {
    return html`<button>${props.label}</button>`;
}, {
    props: {
        label: { type: String, default: "Кнопка" }
    }
});

Особенности работы со свойствами:

  • Свойства автоматически отражаются на DOM через атрибуты.
  • Изменение свойства перерисовывает компонент, сохраняя реактивность.
  • Поддерживаются события на изменение свойств, что упрощает связь компонентов между собой.

Хуки в Atomico

Atomico использует реактивные хуки для управления состоянием, эффектами и ссылками на DOM. Основные хуки:

  • useState(initial) — создаёт локальное состояние.
  • useEffect(callback, deps) — аналог эффекта в React, выполняется при изменении зависимостей.
  • useRef() — создаёт ссылку на DOM-элемент или любое другое значение.
  • useContext(context) — позволяет использовать глобальные состояния через контекст.

Пример с эффектами и ссылками:

const InputFocus = component(() => {
    const inputRef = useRef();

    useEffect(() => {
        inputRef.current.focus();
    }, []);

    return html`<input ref=${inputRef} />`;
});

Реактивные события

Atomico позволяет подписываться на события DOM или собственные события компонента. События передаются через атрибуты с on-префиксом.

const Toggle = component(() => {
    const [on, setOn] = useState(false);

    return html`
        <button oncl ick=${() => setOn(!on)}>
            ${on ? "Вкл" : "Выкл"}
        </button>
    `;
});

Особенности событий:

  • События автоматически обновляют состояние компонента.
  • Можно использовать делегирование и кастомные события через dispatchEvent.

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

Atomico поддерживает локальные стили через тег <style> внутри компонента или через модульные CSS. Стили изолированы для конкретного компонента и не влияют на глобальный DOM.

const StyledButton = component(() => {
    return html`
        <button>Нажми меня</button>
        <style>
            button {
                background: #007acc;
                color: white;
                border: none;
                padding: 8px 16px;
                border-radius: 4px;
                cursor: pointer;
            }
        </style>
    `;
});

Особенности локальных стилей:

  • CSS применяются только к текущему компоненту.
  • Поддерживаются псевдоклассы и вложенные селекторы.
  • Можно использовать динамические стили, меняя свойства через реактивное состояние.

Комбинирование компонентов

Atomico позволяет легко строить иерархию компонентов и использовать их внутри других компонентов. Поддерживается передача свойств, событий и слотов (children).

const App = component(() => {
    return html`
        <div>
            <Counter></Counter>
            <Toggle></Toggle>
        </div>
    `;
});

Особенности комбинации:

  • Любой компонент можно использовать как обычный HTML-тег.
  • Свойства можно передавать напрямую через атрибуты.
  • Дочерние элементы можно передавать через children, что позволяет строить сложные интерфейсы.

Работа с контекстом

Контекст в Atomico позволяет передавать данные через дерево компонентов без необходимости прокидывать их через каждый уровень.

import { createContext } from "atomico";

const ThemeContext = createContext("light");

const ThemedButton = component(() => {
    const theme = useContext(ThemeContext);

    return html`<button class=${theme}>Кнопка</button>`;
});

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

  • Контекст создаётся через createContext.
  • Provider передаёт значение вниз по дереву компонентов.
  • useContext позволяет компоненту получать текущее значение.

Итоговая архитектура приложения

Использование Atomico позволяет строить приложения с компонентной архитектурой, реактивным состоянием и полной изоляцией стилей. Компоненты могут быть мелкими и переиспользуемыми, что ускоряет разработку и снижает сложность управления интерфейсом.

Atomico хорошо интегрируется с Vite, обеспечивая быстрый HMR (Hot Module Replacement) и минимальную задержку при обновлении компонентов, что особенно важно при разработке сложных SPA.