Slim.js — это легковесная библиотека для создания веб-компонентов, которая активно использует подход декларативного программирования и двухстороннего связывания данных. Одной из ключевых практик при работе с библиотекой является разделение логики и представления, что обеспечивает удобство поддержки кода, масштабируемость и тестируемость приложений.
В Slim.js каждый компонент объединяет шаблон разметки и
бизнес-логику. Основной класс компонента наследуется от
Slim, а шаблон определяется через HTML в виде строки или
через тег <template>. Логика компонента реализуется в
виде методов и свойств класса.
import { Slim } from 'slim-js';
class CounterComponent extends Slim {
count = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
}
Slim.define('counter-component', CounterComponent, `
<div>
<button click="decrement">-</button>
<span>{count}</span>
<button click="increment">+</button>
</div>
`);
В этом примере шаблон сосредоточен исключительно на отображении
данных (count) и реакциях на события (click),
тогда как бизнес-логика (increment, decrement)
полностью отделена в методы класса. Такой подход позволяет легко
модифицировать интерфейс без изменения внутренней логики.
Slim.js поддерживает одно- и двустороннее связывание данных с
использованием фигурных скобок {} и директив событий, таких
как click. Это позволяет разделить:
<span>{count}</span>
Эта запись автоматически обновляет отображение при изменении значения
свойства count, без необходимости вручную обращаться к DOM.
Логика управления состоянием полностью скрыта за методами
компонента.
Slim.js предоставляет несколько жизненных циклов компонентов, через которые можно организовать логику:
onBeforeCreated() — выполняется перед инициализацией
DOM. Используется для подготовки данных.onCreated() — выполняется после инициализации. Подходит
для подписок на события или инициализации сервисов.onBeforeUpdate() и onUpdated() — позволяют
обрабатывать изменения данных и выполнять действия до или после
обновления DOM.Пример разделения логики через жизненный цикл:
class TimerComponent extends Slim {
time = 0;
intervalId = null;
onCreated() {
this.startTimer();
}
startTimer() {
this.intervalId = setInterval(() => {
this.time++;
}, 1000);
}
stopTimer() {
clearInterval(this.intervalId);
}
}
Slim.define('timer-component', TimerComponent, `
<div>
<span>{time}</span>
<button click="stopTimer">Stop</button>
</div>
`);
Шаблон остаётся чистым и не содержит логики управления таймером, которая полностью вынесена в методы компонента.
Slim.js автоматически отслеживает изменения свойств класса, что позволяет строить реактивные интерфейсы без прямого вмешательства в DOM. Свойства объявляются как обычные поля класса, и любое их изменение мгновенно отражается в представлении. Это укрепляет принцип разделения ответственности:
class ToggleComponent extends Slim {
isActive = false;
toggle() {
this.isActive = !this.isActive;
}
}
Slim.define('toggle-component', ToggleComponent, `
<div>
<button click="toggle">{isActive ? 'Active' : 'Inactive'}</button>
</div>
`);
Для больших приложений рекомендуется разбивать логику на несколько вложенных компонентов. Slim.js поддерживает композицию компонентов, что позволяет:
Пример:
Slim.define('user-card', class extends Slim {
user = { name: 'Alice', age: 25 };
}, `
<div>
<user-name name="{user.name}"></user-name>
<user-age age="{user.age}"></user-age>
</div>
`);
Slim.define('user-name', class extends Slim {}, `<span>{name}</span>`);
Slim.define('user-age', class extends Slim {}, `<span>{age} years</span>`);
В этом примере user-card отвечает за данные
пользователя, а дочерние компоненты полностью сосредоточены на
отображении конкретных свойств. Такой подход облегчает поддержку и
тестирование.
Эти практики обеспечивают поддержку принципов MVC и реактивного программирования внутри Slim.js, делая код чистым, понятным и легко расширяемым.