Жизненный цикл компонента

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


Создание компонента

Компонент в Slim.js создаётся с помощью объявления класса, наследующегося от Slim:

class MyComponent extends Slim {
  constructor() {
    super();
    this.message = 'Hello, Slim!';
  }
  
  get template() {
    return `<p>{{message}}</p>`;
  }
}
customElements.define('my-component', MyComponent);
  • Конструктор (constructor) выполняется один раз при создании экземпляра компонента.
  • В конструкторе можно задавать начальное состояние и определять свойства.
  • Не следует выполнять манипуляции с DOM, так как элемент ещё не добавлен в документ.

Подключение к DOM

После вставки компонента в DOM вызывается метод connectedCallback:

connectedCallback() {
  super.connectedCallback();
  console.log('Компонент подключен к DOM');
}

Особенности connectedCallback:

  • Вызывается каждый раз, когда элемент добавляется в DOM.
  • Подходит для инициализации внешних ресурсов: подписок, таймеров, запросов к серверу.
  • Если элемент удаляется и снова добавляется, метод вызывается повторно.

Инициализация данных и реактивность

Slim.js использует двустороннюю привязку данных и реактивность. Свойства, определённые через this, автоматически отслеживаются. Для реактивного обновления можно использовать this.trigger() или модифицировать свойства напрямую:

this.message = 'Updated message';

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


Обновление компонента

Метод attributeChangedCallback(name, oldValue, newValue) отслеживает изменения атрибутов:

attributeChangedCallback(name, oldValue, newValue) {
  if (name === 'data-title') {
    this.title = newValue;
  }
}
  • Необходимо объявлять массив наблюдаемых атрибутов:
static get observedAttributes() {
  return ['data-title', 'data-value'];
}
  • Этот механизм позволяет реагировать на внешние изменения, происходящие через HTML-атрибуты.

Рендеринг и обновление DOM

Slim.js использует шаблонный рендеринг через геттер template. При изменении свойств:

  1. Сравниваются старые и новые значения.
  2. Выполняются минимальные изменения в DOM.
  3. Если используется массив или объект, рекомендуется использовать ключи (key) для оптимизации.

Пример условного рендеринга:

get template() {
  return `
    <div>
      {{#if showMessage}}
        <p>{{message}}</p>
      {{/if}}
    </div>
  `;
}
  • {{#if ...}} позволяет управлять видимостью элементов без удаления компонента полностью.

Отключение и уничтожение

Метод disconnectedCallback вызывается при удалении компонента из DOM:

disconnectedCallback() {
  super.disconnectedCallback();
  console.log('Компонент удалён из DOM');
  // Очистка ресурсов
  clearInterval(this.timer);
}
  • В этом методе важно очищать таймеры, отменять подписки и удалять обработчики событий, чтобы избежать утечек памяти.
  • Подходит для любых операций, связанных с “размонтированием” компонента.

Асинхронные операции и жизненный цикл

Для асинхронных операций (загрузка данных, API-запросы) рекомендуется:

  1. Запускать операции в connectedCallback.
  2. Проверять, что компонент всё ещё находится в DOM перед обновлением состояния.
  3. Использовать disconnectedCallback для отмены или очистки промисов и подписок.

Пример:

connectedCallback() {
  super.connectedCallback();
  this.fetchData();
}

async fetchData() {
  const response = await fetch('/api/data');
  if (this.isConnected) {
    this.data = await response.json();
  }
}

Совмещение методов жизненного цикла

Slim.js позволяет комбинировать конструктор, connectedCallback, attributeChangedCallback и disconnectedCallback для полной настройки поведения компонента. Хорошая практика:

  • Конструктор — инициализация состояния.
  • connectedCallback — подключение к DOM и внешним ресурсам.
  • attributeChangedCallback — реакция на изменения атрибутов.
  • disconnectedCallback — очистка ресурсов.

Эта структура обеспечивает предсказуемое поведение компонентов, минимизирует ошибки при динамическом добавлении и удалении элементов и позволяет использовать реактивные возможности Slim.js на полную мощность.


Важные нюансы жизненного цикла

  • Методы жизненного цикла могут вызываться несколько раз в течение жизни компонента.
  • connectedCallback может вызываться многократно при перемещении элемента в DOM.
  • attributeChangedCallback вызывается только при изменении наблюдаемых атрибутов.
  • Для оптимизации обновлений лучше избегать прямой манипуляции DOM внутри attributeChangedCallback — лучше изменять свойства, которые автоматически триггерят рендер.

Жизненный цикл в Slim.js — фундамент для построения устойчивых, реактивных компонентов с предсказуемым поведением, позволяющий управлять ресурсами и асинхронными операциями без утечек памяти.