Slim.js — это лёгкая библиотека для создания веб-компонентов, ориентированная на производительность и минимальный размер кода. Она обеспечивает декларативный подход к разработке интерфейсов, позволяя определять компоненты как на уровне шаблонов HTML, так и через JavaScript-классы. Основной концепцией является связь данных и представления с минимальным вмешательством в DOM.
Особенности Slim.js:
Slim.tag.Для определения нового компонента используется функция
Slim.tag. Синтаксис следующий:
Slim.tag('my-component', class extends Slim {
get template() {
return `
<div>
<h1>{{title}}</h1>
<p>{{description}}</p>
</div>
`;
}
onBeforeCreated() {
this.title = 'Заголовок компонента';
this.description = 'Описание компонента';
}
});
template возвращает строку с HTML-шаблоном, где данные
оборачиваются двойными фигурными скобками {{ }}.onBeforeCreated позволяет инициализировать реактивные
свойства до монтирования в DOM.Slim.js реализует одностороннюю реактивность: изменения свойств автоматически отражаются в DOM. Для обновления данных достаточно присвоить новое значение свойству:
this.title = 'Новый заголовок';
Для более сложных случаев возможно использование наблюдателей:
this.observe('title', (newValue, oldValue) => {
console.log(`Title изменён с ${oldValue} на ${newValue}`);
});
Slim.js позволяет удобно работать с событиями:
<button click="increment()">Нажать</button>
<span>{{counter}}</span>
Slim.tag('counter-component', class extends Slim {
onBeforeCreated() {
this.counter = 0;
}
increment() {
this.counter++;
}
});
Метод increment автоматически связывается с атрибутом
click в шаблоне. Это обеспечивает чистую
декларативную привязку событий без использования
addEventListener.
Slim.js предоставляет несколько хуков жизненного цикла:
onBeforeCreated — перед созданием элемента,
инициализация данных.onAfterCreated — после создания элемента, можно
выполнять DOM-операции.onBeforeUpdate — перед обновлением DOM при изменении
реактивных свойств.onAfterUpdate — после обновления DOM, полезно для
сторонней интеграции.Пример использования:
Slim.tag('lifecycle-component', class extends Slim {
onBeforeCreated() {
this.text = 'Инициализация';
}
onAfterCreated() {
console.log('Компонент создан');
}
onAfterUpdate() {
console.log('DOM обновлён, текущее значение:', this.text);
}
});
Slim.js поддерживает слоты, позволяя создавать составные компоненты с гибкой вставкой контента:
Slim.tag('card-component', class extends Slim {
get template() {
return `
<div class="card">
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
`;
}
});
Использование:
<card-component>
<h2 slot="header">Заголовок</h2>
<p>Основной контент</p>
<div slot="footer">Подвал</div>
</card-component>
Слоты обеспечивают гибкую композицию компонентов, что критично при построении сложных интерфейсов и micro-frontends.
Micro-frontends предполагают разбиение интерфейса на независимые, изолированные части, которые могут разрабатываться и деплоиться отдельно. Slim.js идеально подходит для этой архитектуры благодаря лёгкости и изоляции компонентов:
Пример взаимодействия двух micro-frontends:
<user-card id="user1" user-name="Иван"></user-card>
<user-actions for-user="user1"></user-actions>
Компонент user-actions может получать события от
user-card через кастомные события, обеспечивая
независимость модулей.
Для micro-frontends критично уменьшение нагрузки на основной bundle. Slim.js поддерживает динамическую загрузку компонентов:
async function loadComponent(name) {
const module = await import(`./components/${name}.js`);
return module;
}
loadComponent('user-card').then(() => {
document.body.appendChild(document.createElement('user-card'));
});
Это позволяет лениво загружать интерфейсные блоки, сохраняя быстрый рендеринг страницы и минимальный первоначальный вес.
Slim.js можно использовать с внешними хранилищами состояния, например Redux или Zustand, благодаря реактивной привязке данных:
store.subscribe(() => {
userCard.name = store.getState().userName;
});
Это позволяет синхронизировать глобальное состояние с локальными компонентами, что особенно важно при масштабных micro-frontends.
Slim.js не накладывает ограничений на стили, но рекомендуется использовать Shadow DOM для изоляции:
Slim.tag('shadow-card', class extends Slim {
get useShadow() { return true; }
get template() {
return `<p>Контент с изолированными стилями</p>`;
}
});
Изоляция стилей предотвращает конфликты между micro-frontends и упрощает поддержку крупного интерфейса.
Slim.js сочетает:
Это делает библиотеку удобным инструментом для модульных, производительных и легко масштабируемых интерфейсов в современных веб-приложениях.