CustomEvent и передача данных

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

Создание и отправка событий

В Atomico для отправки пользовательских событий используется функция emit, которая возвращается при вызове useEvent. События могут содержать произвольные данные, которые будут доступны в обработчике.

Пример создания события с данными:

import { c, useEvent } from "atomico";

function Counter() {
    const emit = useEvent("count-change");

    let count = 0;

    const increment = () => {
        count++;
        emit({ value: count });
    };

    return (
        <host shadowDom>
            <button oncl ick={increment}>Увеличить: {count}</button>
        </host>
    );
}

Counter.props = {};
export default c(Counter);

В этом примере useEvent("count-change") создаёт функцию emit, которая генерирует событие с именем "count-change" и передаёт объект { value: count } в качестве payload. Этот объект становится доступным в слушателе события на родительском элементе.

Подписка на пользовательские события

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

import { c } from "atomico";
import Counter from "./Counter";

function App() {
    const handleCountChange = (event) => {
        console.log("Новое значение счётчика:", event.detail.value);
    };

    return (
        <host>
            <Counter onCount-change={handleCountChange} />
        </host>
    );
}

App.props = {};
export default c(App);

Здесь onCount-change автоматически подписывается на событие "count-change", и event.detail.value содержит значение, переданное компонентом Counter.

Передача сложных данных

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

emit({
    value: count,
    timestamp: Date.now(),
    callback: () => console.log("Событие обработано"),
});

На стороне родителя можно вызвать event.detail.callback() для выполнения переданной функции.

События с опциями

CustomEvent позволяет задавать опции bubbles и composed, что особенно полезно при работе со Shadow DOM:

const emit = useEvent("custom-event", { bubbles: true, composed: true });
emit({ message: "Привет!" });
  • bubbles: событие всплывает вверх по DOM.
  • composed: событие проходит сквозь границы Shadow DOM.

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

Рекомендации по передаче данных

  1. Использовать объекты в detail для расширяемости. Добавление новых полей не нарушает существующих обработчиков.
  2. Передавать только необходимые данные — избегать больших и тяжёлых объектов без надобности.
  3. Для передачи функций и колбэков учитывать, что они будут ссылками на оригинальные функции, поэтому их вызов изменяет контекст родительского компонента.

Итоговые возможности

Механизм CustomEvent в Atomico объединяет преимущества стандартных событий браузера и реактивной модели библиотек. Он обеспечивает:

  • Простую передачу данных из дочернего компонента к родителю.
  • Гибкость в работе с объектами, массивами и колбэками.
  • Контроль над всплытием и взаимодействием со Shadow DOM.
  • Минимизацию связей между компонентами при сохранении полной функциональности.

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