Динамическое создание компонентов

Библиотека Slim.js предоставляет выразительный механизм определения веб-компонентов и позволяет создавать их экземпляры динамически через JavaScript. Под динамическим созданием подразумевается инициализация компонента в рантайме, когда его наличие в DOM не было заранее задано HTML-разметкой.

Основные принципы

Slim.js регистрирует компоненты через наследование Slim или Slim.Element, а затем позволяет создавать новые экземпляры при помощи стандартных веб-API. Ключевой момент заключается в том, что после регистрации компонента его можно использовать так же, как нативный DOM-элемент.

Пример регистрации компонента:

class TodoItem extends Slim {
  static get tag() { return 'todo-item'; }
  static get useShadow() { return true; }

  onCreated() {
    this.innerHTML = `
      <div class="item">
        <span bind="text"></span>
      </div>
    `;
  }

  set text(value) {
    this._text = value;
    this.update();
  }

  get text() {
    return this._text;
  }
}

Slim.register(TodoItem);

После регистрации компонент становится доступен через тег <todo-item> и может создаваться как в HTML, так и программно.

Создание экземпляров в рантайме

Slim.js не добавляет собственных методов для динамической генерации. Создание выполняется стандартным способом:

const item = document.createElement('todo-item');
item.text = 'Купить хлеб';
document.querySelector('#list').appendChild(item);

Важным аспектом является протекание жизненного цикла компонента. После добавления в DOM Slim.js автоматически вызывает onCreated, затем реактивные привязки и обновления интерфейса.

Работа со свойствами и реактивностью

Любое публичное свойство компонента может устанавливаться до или после добавления в DOM. Однако Slim.js применяет реактивное обновление только после монтирования. Поэтому часто используется схема:

  1. Создание экземпляра.
  2. Установка данных.
  3. Добавление в DOM.

Slim.js отслеживает изменения свойств, указываемых в привязках (bind="..."), и обновляет DOM без явных вызовов ререндеринга.

Динамическая генерация коллекций

Для генерации коллекций элементов Slim.js не навязывает декларативного механизма. Привычный цикл JavaScript или обработчики событий могут формировать массив экземпляров. Такой подход позволяет контролировать и порядок элементов, и вложенность.

const list = document.querySelector('#list');
const tasks = ['Купить хлеб', 'Оплатить счета', 'Позвонить Марии'];

tasks.forEach(text => {
  const item = document.createElement('todo-item');
  item.text = text;
  list.appendChild(item);
});

Динамическое создание особенно уместно при работе со списками, вкладками, карточками, таблицами и другими интерфейсными структурами, где количество элементов неизвестно заранее.

Интеграция с данными и сетевыми запросами

Компоненты, создаваемые после загрузки данных с сервера, отражают гибкость Slim.js. Данные могут поступать через fetch или любой другой источник, а затем отображаться в виде набора компонентных экземпляров:

fetch('/api/tasks')
  .then(r => r.json())
  .then(tasks => {
    tasks.forEach(t => {
      const item = document.createElement('todo-item');
      item.text = t.title;
      list.appendChild(item);
    });
  });

Slim.js не вводит собственной модели данных, что делает интеграцию с внешними хранилищами или состоянием приложения нейтральной и незатруднённой.

Удаление и управление жизненным циклом

Динамически созданные компоненты могут удаляться так же, как и другие DOM-элементы:

list.removeChild(item);

При удалении Slim.js корректно завершает внутренние процессы компонента. Если компонент использует обработчики событий, ресурсы или подписки, их освобождение следует реализовать вручную в onRemoved, чтобы избегать утечек.

class MyComponent extends Slim {
  onRemoved() {
    // освобождение ресурсов
  }
}

Комбинация динамики и шаблонов

Slim.js позволяет комбинировать шаблоны, задаваемые строками, с динамическими элементами. Благодаря этому создаётся интерфейс, в котором часть верстки статична, а часть формируется программно. Динамически созданные элементы остаются полноценными компонентами с реактивностью и привязками.

Использование слотов при динамическом создании

Если компонент использует слоты, внутрь него могут передаваться DOM-узлы и другие компоненты:

const card = document.createElement('ui-card');
const content = document.createElement('p');
content.textContent = 'Описание товара';

card.appendChild(content);
document.body.appendChild(card);

Slim.js корректно вставит узлы в слот, сохранив семантику и структуру.

Динамическое создание в сложных интерфейсах

В многоуровневых интерфейсах, где дерево компонентно ориентировано, динамическое создание позволяет добавлять вложенные элементы в зависимости от состояния приложения. Slim.js при этом не навязывает архитектурных ограничений: различные уровни компонентов могут взаимодействовать через свойства, события, публичные методы и контекст окружения.

Применение событий и связи компонент

Для коммуникации компонентов, созданных динамически, используются кастомные события или собственные API класса:

item.addEventListener('done', e => {
  console.log('Задача завершена:', e.detail);
});

Динамически созданные компоненты органично вписываются в событийную модель браузера. Slim.js обеспечивает привязку on:event в шаблоне и dispatchEvent внутри компонентов.

Ключевые особенности

  • Создание через стандартный DOM-API.
  • Отсутствие дополнительного слоя абстракции.
  • Реактивность через свойства с привязками.
  • Естественная интеграция с данными и сетевыми запросами.
  • Поддержка жизненного цикла и слотов.
  • Возможность наращивания интерфейса в рантайме.

Динамическое создание компонентов в Slim.js органично вписывается в модель веб-компонентов и усиливает гибкость при проектировании интерфейсов любой сложности.