Code review guidelines

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

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


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

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

import Slim from 'slim-js';

class MyComponent extends Slim {
  static get observedAttributes() {
    return ['title', 'count'];
  }

  onBeforeCreated() {
    this.count = 0;
  }

  increment() {
    this.count++;
  }

  get template() {
    return `
      <div>
        <h1>{{title}}</h1>
        <p>Count: {{count}}</p>
        <button oncl ick="increment()">Increment</button>
      </div>
    `;
  }
}

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

Ключевые моменты:

  • observedAttributes — список атрибутов, за изменениями которых Slim.js следит автоматически.
  • onBeforeCreated — метод жизненного цикла, вызываемый перед монтированием компонента.
  • template — геттер, возвращающий HTML-шаблон с биндингом к свойствам компонента.

Реактивные свойства

Slim.js обеспечивает двустороннюю реактивность свойств. Изменение значения свойства автоматически обновляет DOM.

this.title = 'Новый заголовок';

Если свойство было указано в шаблоне через {{title}}, соответствующий элемент обновится без ручного вмешательства.

Совет: избегать больших вычислений внутри шаблона. Для сложной логики лучше использовать методы и вычисляемые свойства.


Атрибуты и свойства

Slim.js различает HTML-атрибуты и свойства компонента. Атрибуты приходят извне через DOM, свойства — внутренние реактивные данные.

<my-component title="Пример"></my-component>

В компоненте title автоматически синхронизируется с атрибутом. Любое изменение this.title отражается на DOM и обратно, если используется привязка к атрибуту.


Обработка событий

События можно назначать как через HTML-шаблон, так и через методы компонента. Slim.js автоматически связывает контекст методов с экземпляром компонента.

get template() {
  return `<button oncl ick="handleClick()">Click me</button>`;
}

handleClick() {
  console.log('Button clicked', this.count);
}

Для кастомных событий используется стандартный механизм CustomEvent:

this.dispatchEvent(new CustomEvent('updated', { detail: this.count }));

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

Slim.js предоставляет набор методов жизненного цикла:

  • onBeforeCreated() — инициализация данных перед рендером.
  • onCreated() — вызов после создания компонента и привязки к DOM.
  • onBeforeUpdate() — перед обновлением шаблона.
  • onUpdated() — после обновления DOM.
  • onRemoved() — перед удалением компонента из DOM.

Использование этих методов позволяет контролировать поведение компонента на всех этапах его жизни.


Шаблонная разметка

Slim.js поддерживает инлайновый HTML с биндингом, что упрощает работу с динамическими данными:

get template() {
  return `
    <div class="{{className}}">
      <p>{{message}}</p>
    </div>
  `;
}

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


Директивы Slim.js

Slim.js предоставляет ряд встроенных директив для работы с условным рендерингом и списками:

  • if — условное отображение элемента.
  • repeat — рендеринг массивов или коллекций.
  • bind — привязка событий или значений к свойствам.

Пример с repeat:

get template() {
  return `
    <ul>
      <li repeat="{{item in items}}">{{item}}</li>
    </ul>
  `;
}

Любое изменение массива this.items автоматически обновляет список в DOM.


Стилизация компонентов

Slim.js позволяет инкапсулировать стили через <style> внутри шаблона:

get template() {
  return `
    <style>
      p { color: blue; }
    </style>
    <p>{{message}}</p>
  `;
}

Стили применяются только к конкретному компоненту, что предотвращает глобальные конфликты.


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

Slim.js легко встраивается в проекты без полного фреймворка. Компоненты могут сосуществовать с обычным HTML, React, Vue или Angular. Использование веб-компонентов обеспечивает совместимость с любым современным браузером.


Оптимизация производительности

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

Рекомендации:

  • Разделять большие компоненты на мелкие, чтобы уменьшить количество перерендеров.
  • Использовать методы жизненного цикла для управления тяжелыми вычислениями.
  • Избегать вложенных шаблонов без необходимости.

Работа с состоянием

Для глобального состояния Slim.js не предоставляет встроенного сторедж-решения, но легко интегрируется с внешними библиотеками, например Redux или MobX. Локальные свойства компонента могут быть реактивными и служить источником состояния для UI.


Модульность и переиспользование

Компоненты Slim.js могут быть легко импортированы и экспортированы как отдельные модули ES6:

export class ButtonComponent extends Slim { ... }
import { ButtonComponent } from './ButtonComponent.js';

Это позволяет строить масштабируемые приложения с чистой архитектурой.


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