Миграция с других фреймворков

При переходе с крупных JavaScript-фреймворков, таких как React, Vue или Angular, на Slim.js, ключевое отличие заключается в минималистичном подходе к структуре приложения и управлению состоянием. Slim.js не требует обширной архитектуры или сложных систем роутинга и управления зависимостями, что значительно упрощает начальный порог освоения, но требует понимания фундаментальных принципов реактивного обновления DOM и жизненного цикла компонентов.


Компонентная модель Slim.js

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

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

class MyComponent extends Slim {
  get template() {
    return `<div>Hello, {name}!</div>`;
  }

  constructor() {
    super();
    this.name = 'Slim.js';
  }
}

customElements.define('my-component', MyComponent);

Ключевые особенности по сравнению с React или Vue:

  • Простая реактивность: Все свойства, определённые в классе компонента, автоматически становятся реактивными. Нет необходимости использовать state, props или ref.
  • Минимальный синтаксис: Встроенная поддержка привязки данных через {property}.
  • Прямое управление DOM: Slim.js обновляет только те части DOM, которые изменились, без виртуального DOM, что уменьшает накладные расходы.

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

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

  • onBeforeCreated(): вызывается перед созданием компонента.
  • onCreated(): компонент создан, но DOM ещё не привязан.
  • onBeforeRender(): вызывается перед рендерингом шаблона.
  • onAfterRender(): DOM уже обновлён и готов к взаимодействию.
  • onAttributeChanged(name, oldValue, newValue): отслеживание изменений атрибутов компонента.

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

class Counter extends Slim {
  get template() {
    return `<button oncl ick="{increment}">{count}</button>`;
  }

  constructor() {
    super();
    this.count = 0;
  }

  increment() {
    this.count++;
  }

  onAfterRender() {
    console.log('Компонент отрендерен, текущий счёт: ', this.count);
  }
}

customElements.define('my-counter', Counter);

Переходя с React или Vue, следует учитывать, что Slim.js не требует использования useEffect, watchers или computed. Все свойства автоматически реагируют на изменения.


Управление состоянием

Slim.js не навязывает глобальные менеджеры состояния, такие как Redux или Vuex. Для хранения и обмена данными между компонентами можно использовать:

  1. Свойства и атрибуты компонентов. Компоненты могут принимать данные через атрибуты и обновлять их реактивно.
  2. События CustomEvent. Для коммуникации между компонентами используются стандартные DOM-события:
this.dispatchEvent(new CustomEvent('update', { detail: this.count }));
  1. Внешние объекты состояния. Можно создать объект состояния и подписывать на него компоненты через Slim.observe():
const state = { value: 0 };
Slim.observe(state, 'value', () => console.log('Value changed:', state.value));

Работа с шаблонами и привязкой данных

В отличие от JSX или шаблонов Vue, Slim.js использует синтаксис {property} для динамических данных. Поддерживаются:

  • Вставка значений свойств.
  • Обработка событий через {methodName}.
  • Условные блоки с {{#if condition}} ... {{/if}}.
  • Циклы с {{#each items}} ... {{/each}}.

Пример цикла:

class ListComponent extends Slim {
  get template() {
    return `
      <ul>
        {{#each items}}
          <li>{this}</li>
        {{/each}}
      </ul>
    `;
  }

  constructor() {
    super();
    this.items = ['Slim', 'React', 'Vue'];
  }
}

customElements.define('my-list', ListComponent);

Роутинг и интеграция с существующими проектами

Slim.js не содержит встроенного роутера, поэтому при миграции нужно:

  • Использовать сторонние роутеры, такие как Navigo или Page.js.
  • Интегрировать Slim.js-компоненты в существующую структуру, заменяя отдельные части интерфейса, чтобы минимизировать полную переделку.

Пример интеграции с Navigo:

const router = new Navigo('/');
router.on('/home', () => {
  document.querySelector('#app').innerHTML = `<home-page></home-page>`;
});
router.resolve();

Основные ошибки при миграции

  1. Попытка использовать JSX или Vue-шаблоны. Slim.js не поддерживает JSX и синтаксис Vue, необходимо адаптировать шаблоны.
  2. Игнорирование реактивности свойств. Важно определить все свойства компонента заранее, иначе изменения не будут отслеживаться.
  3. Неправильная работа с событиями. В Slim.js необходимо использовать {methodName} или стандартные DOM-события, а не addEventListener внутри render().
  4. Неправильное взаимодействие с внешними состояниями. Все глобальные данные должны быть реактивно отслеживаемыми через Slim.observe или события.

Рекомендации по оптимизации

  • Минимизировать количество свойств для больших компонентов. Slim.js оптимизирует обновление DOM, но излишняя реактивность может замедлить рендеринг.
  • Использовать отдельные компоненты для повторяющихся блоков интерфейса.
  • При работе с массивами и списками всегда использовать цикл {{#each}} для реактивного обновления вместо прямого DOM-манипулирования.

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