Объявление наблюдаемых атрибутов

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


Свойство observedAttributes

В Atomico для того, чтобы компонент мог реагировать на изменение атрибутов DOM, используется статическое свойство observedAttributes. Оно принимает массив строк, каждая из которых соответствует имени атрибута, за которым компонент будет следить.

import { c, html } from "atomico";

function MyComponent({ color }) {
    return html`
        <div style="color: ${color}">Привет, Atomico!</div>
    `;
}

MyComponent.observedAttributes = ["color"];

customElements.define("my-component", c(MyComponent));

В этом примере компонент будет автоматически реагировать на изменение атрибута color, обновляя визуальное состояние.


Синхронизация атрибутов и свойств

Atomico обеспечивает двухстороннюю связь между атрибутами DOM и свойствами компонента. Когда атрибут изменяется через HTML или JavaScript, соответствующее свойство компонента обновляется.

const el = document.createElement("my-component");
el.setAttribute("color", "red");
console.log(el.color); // "red"

При этом библиотека автоматически конвертирует атрибуты в соответствующие типы данных. Для строк и булевых значений синхронизация происходит напрямую, а для чисел или сложных объектов может потребоваться ручное преобразование через getter/setter.


Работа с булевыми атрибутами

Булевые атрибуты требуют особого подхода. Если атрибут присутствует — его значение считается true, если отсутствует — false. Atomico учитывает этот механизм при связывании с пропсами.

function Toggle({ active }) {
    return html`<button>${active ? "Включено" : "Выключено"}</button>`;
}

Toggle.observedAttributes = ["active"];
const toggle = document.createElement("toggle-component");
toggle.setAttribute("active", "");
console.log(toggle.active); // true
toggle.removeAttribute("active");
console.log(toggle.active); // false

Такой подход позволяет реализовать реактивные интерфейсы без дополнительного кода для отслеживания изменений.


Динамическое отслеживание

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

MyComponent.observedAttributes = ["color", "size"];

После такого обновления компонент будет реагировать как на изменение color, так и на size. Это упрощает масштабирование компонентов и интеграцию с разными API.


Обработка изменений через onChange

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

function MyComponent({ value }) {
    const [internalValue, setInternalValue] = useState(value);

    useEffect(() => {
        console.log("Значение атрибута изменилось:", value);
    }, [value]);

    return html`<p>${internalValue}</p>`;
}

MyComponent.observedAttributes = ["value"];

Каждое изменение атрибута автоматически триггерит обновление пропса value, что позволяет реализовать реактивную логику, аналогичную подписке на события.


Принципы декларативного подхода

  1. Явное указание наблюдаемых атрибутов повышает читаемость и предсказуемость компонентов.
  2. Синхронизация DOM ↔︎ пропсы позволяет избавиться от ручного слушателя attributeChangedCallback.
  3. Реактивные обновления через useState и useEffect делают управление состоянием компонентного дерева согласованным и предсказуемым.
  4. Булевыe атрибуты интегрируются с логикой пропсов без дополнительных проверок.

Особенности реализации в Atomico

  • observedAttributes поддерживается только на уровне функциональных компонентов и статических свойств.
  • Атрибуты всегда интерпретируются как строки, поэтому при необходимости работы с числами или JSON нужно использовать getter/setter или внутреннее состояние.
  • Atomico обеспечивает автоматическую перерисовку при изменении наблюдаемых атрибутов, что устраняет необходимость вручную вызывать requestUpdate.

Пример комплексного использования

function Card({ title, highlighted }) {
    return html`
        <div style="border: ${highlighted ? "2px solid gold" : "1px solid gray"}">
            <h3>${title}</h3>
        </div>
    `;
}

Card.observedAttributes = ["title", "highlighted"];

customElements.define("x-card", c(Card));
<x-card title="Atomico" highlighted></x-card>

При изменении атрибута highlighted через JavaScript или пользовательский ввод, компонент автоматически обновляет внешний вид без дополнительного кода.


Наблюдаемые атрибуты в Atomico позволяют сократить шаблонный код, сделать компоненты реактивными и легко интегрируемыми в различные интерфейсы. Правильное использование observedAttributes обеспечивает чистоту архитектуры, прозрачную синхронизацию DOM и пропсов, а также упрощает масштабирование сложных веб-компонентов.