Slim.js — это лёгкая и высокопроизводительная библиотека для построения веб-компонентов с реактивным состоянием. Одной из ключевых возможностей Slim.js является поддержка middleware и плагинов для работы с состоянием, что позволяет гибко управлять потоками данных и расширять функциональность компонентов.
Middleware в Slim.js представляет собой промежуточный слой между изменением состояния и его отражением в DOM. Он позволяет перехватывать, модифицировать или фильтровать данные перед их применением к компоненту.
Основные задачи middleware:
Пример использования middleware:
import { Slim, middleware } from 'slim-js';
const logMiddleware = (state, next) => {
console.log('Состояние до изменения:', state);
next(state); // передаёт управление следующему middleware или обновлению компонента
console.log('Состояние после изменения:', state);
};
class Counter extends Slim {
static get use() {
return [middleware(logMiddleware)];
}
constructor() {
super();
this.count = 0;
}
increment() {
this.count++;
}
render() {
return `<button oncl ick="${() => this.increment()}">Count: ${this.count}</button>`;
}
}
customElements.define('my-counter', Counter);
В этом примере middleware logMiddleware перехватывает
все изменения состояния компонента, что позволяет контролировать процесс
обновления и отлаживать приложения.
Плагины в Slim.js — это расширения, которые интегрируются с системой состояния и добавляют новые возможности без модификации базового компонента. Плагины могут предоставлять:
import { Slim, plugin } from 'slim-js';
const localStoragePlugin = plugin((component, key) => {
const savedValue = localStorage.getItem(key);
if (savedValue !== null) {
component[key] = JSON.parse(savedValue);
}
component.onChange(key, (value) => {
localStorage.setItem(key, JSON.stringify(value));
});
});
class TodoList extends Slim {
static get use() {
return [localStoragePlugin];
}
constructor() {
super();
this.todos = [];
}
addTodo(todo) {
this.todos = [...this.todos, todo];
}
render() {
return `
<ul>
${this.todos.map(todo => `<li>${todo}</li>`).join('')}
</ul>
<input type="text" onkeypr ess="${(e) => {
if (e.key === 'Enter') this.addTodo(e.target.value);
}}">
`;
}
}
customElements.define('todo-list', TodoList);
Этот плагин автоматически сохраняет и восстанавливает состояние
компонента из localStorage, обеспечивая простую
персистентность данных.
Slim.js поддерживает вычисляемые свойства, которые обновляются автоматически при изменении зависимостей. Middleware и плагины могут использовать эту возможность для оптимизации и кэширования данных.
class ProductList extends Slim {
constructor() {
super();
this.products = [];
this.filter = '';
}
get filteredProducts() {
return this.products.filter(p => p.name.includes(this.filter));
}
render() {
return `
<input type="text" onin put="${(e) => this.filter = e.target.value}" placeholder="Фильтр">
<ul>
${this.filteredProducts.map(p => `<li>${p.name}</li>`).join('')}
</ul>
`;
}
}
customElements.define('product-list', ProductList);
Использование вычисляемых свойств совместно с middleware позволяет, например, логировать фильтрацию, синхронизировать её с сервером или кэшировать результаты для ускорения ререндеринга.
Slim.js позволяет комбинировать несколько middleware и плагинов одновременно. Порядок подключения имеет значение: middleware вызываются по цепочке в порядке подключения, а плагины — в порядке регистрации.
class App extends Slim {
static get use() {
return [middleware(logMiddleware), localStoragePlugin];
}
constructor() {
super();
this.data = '';
}
render() {
return `<div>${this.data}</div>`;
}
}
customElements.define('my-app', App);
Такой подход обеспечивает гибкость управления состоянием и позволяет строить сложные реактивные компоненты с минимальной связностью.
next
для передачи управления следующему слою.onChange и добавлять реактивную логику.