Если компонент не атомарен, и сам по-себе работать не может - это не должен быть компонент, это модуль. Если компонент и его модуль атомарен - то он должен быть продекларирован только в верстке, чтобы обеспечить реиспользуемость и поддержать консистентность.
Идея в отделении логики реиспользуемого компонента от интеграционной логики.
Модуль с логикой должен возвращать конструктор, и ничего не должен знать про css/верстку. Модуль с интеграцией должен служить адаптером, между нашей версткой/css классами.
Конструктор логики принимает словарь с параметрами и словарь с элементами.
Если нужно из "страничного компонента" подтянуть и продекларировать какой-то компонент на верстке - то подтягивается не компонент, а модуль логики.
Общение внутри компонента, который подтянул специфичные модули - только интерфейсное. Модуль не должен слушать кастомные события, все взамодействия по интерфейсам.
Взаимодействие между компонентами, сквозь асинхронный await, а дальше так же через интерфейсы.
Взаимодействие лежит в интеграционном слое.
Интеграционный слой возвращает публичный интерфейс компонента, абстрагируя интерфейс логики и взаимодействия.