Slim.js предоставляет компактный и эффективный способ управления состоянием компонентов, позволяя хранить данные, которые принадлежат конкретному экземпляру компонента и автоматически отражаются в его шаблоне. Локальное состояние является ключевым элементом для построения реактивных интерфейсов без необходимости глобального управления данными.
Локальное состояние компонента в Slim.js определяется через свойства класса, декорированные или просто объявленные внутри класса компонента. Каждое свойство, которое будет участвовать в рендеринге или в реактивной логике, автоматически отслеживается системой Slim.js.
Пример простого компонента с локальным состоянием:
import { Slim, html } from 'slim-js';
class CounterComponent extends Slim {
count = 0;
increment() {
this.count++;
}
render() {
return html`
<div>
<p>Текущее значение: ${this.count}</p>
<button oncl ick=${() => this.increment()}>Увеличить</button>
</div>
`;
}
}
customElements.define('counter-component', CounterComponent);
В этом примере свойство count является локальным
состоянием. Любое его изменение автоматически инициирует перерисовку
шаблона.
Система реактивности в Slim.js основана на отслеживании изменений локальных свойств компонента. При изменении состояния Slim.js автоматически вызывает рендеринг только для тех частей DOM, которые зависят от изменённого значения.
Особенности реактивности:
push, splice, map с
перезаписью).class TodoList extends Slim {
todos = [];
addTodo(item) {
this.todos = [...this.todos, item]; // перезаписываем массив для реактивного обновления
}
render() {
return html`
<ul>
${this.todos.map(todo => html`<li>${todo}</li>`)}
</ul>
<button oncl ick=${() => this.addTodo('Новая задача')}>Добавить</button>
`;
}
}
Перезапись массива через спред-оператор необходима, чтобы Slim.js смог обнаружить изменение и обновить DOM.
Состояние может инициализироваться напрямую при объявлении свойства
или через метод onConnected, который выполняется после
добавления компонента в DOM. Это полезно для начальной загрузки данных,
выполнения асинхронных операций и настройки внутренних зависимостей.
class UserProfile extends Slim {
user = null;
async onConnected() {
this.user = await fetchUserData();
}
render() {
if (!this.user) return html`<p>Загрузка...</p>`;
return html`<p>Имя пользователя: ${this.user.name}</p>`;
}
}
Использование onConnected позволяет безопасно обращаться
к DOM и загружать данные перед отображением.
Slim.js поддерживает вычисляемые свойства, которые зависят от локального состояния. Такие свойства не хранятся напрямую, но пересчитываются при изменении зависимых данных.
class ShoppingCart extends Slim {
items = [];
get total() {
return this.items.reduce((sum, item) => sum + item.price, 0);
}
render() {
return html`
<ul>
${this.items.map(item => html`<li>${item.name}: ${item.price} ₽</li>`)}
</ul>
<p>Итого: ${this.total} ₽</p>
`;
}
}
Вычисляемое свойство total автоматически пересчитывается
при изменении массива items, что позволяет держать
интерфейс синхронизированным без ручного вызова методов обновления.
Компоненты Slim.js часто взаимодействуют с локальным состоянием через пользовательские события или внутренние методы. События позволяют компонентам сообщать о состоянии родителям или соседям, сохраняя при этом локальную реактивность.
class ToggleSwitch extends Slim {
isOn = false;
toggle() {
this.isOn = !this.isOn;
this.dispatchEvent(new CustomEvent('toggle', { detail: this.isOn }));
}
render() {
return html`
<button oncl ick=${() => this.toggle()}>
${this.isOn ? 'Вкл' : 'Выкл'}
</button>
`;
}
}
Использование dispatchEvent делает компонент независимым
и позволяет другим элементам реагировать на изменения состояния без
прямого доступа к внутренним свойствам.
Локальное состояние в Slim.js объединяет простоту объявления свойств с мощной реактивной системой, позволяя создавать динамичные, эффективные и управляемые компоненты без лишнего кода.