Slim.js — это легковесная библиотека для построения компонентного интерфейса на JavaScript, ориентированная на минимализм и декларативное управление DOM. Правильная структура проекта критически важна для поддерживаемости и масштабируемости приложений, особенно при работе с большим количеством компонентов.
Рекомендуемая структура проекта строится вокруг компонентов и их логики:
/project-root
│
├─ /src
│ ├─ /components
│ │ ├─ header.slim.js
│ │ ├─ footer.slim.js
│ │ └─ card.slim.js
│ │
│ ├─ /views
│ │ ├─ home.slim.js
│ │ └─ about.slim.js
│ │
│ ├─ /services
│ │ └─ api.js
│ │
│ ├─ /store
│ │ └─ appState.js
│ │
│ └─ main.js
│
├─ /public
│ └─ index.html
│
├─ package.json
└─ webpack.config.js
components — здесь находятся отдельные
UI-компоненты Slim.js, которые могут быть повторно использованы. Каждый
компонент представлен отдельным файлом .slim.js.views — страницы или контейнерные
компоненты, объединяющие несколько мелких компонентов.services — модуль для работы с API или
другими внешними ресурсами.store — глобальное состояние
приложения, управляемое через Slim.js и кастомные подписки.main.js — точка входа приложения, где
происходит инициализация компонентов и их монтирование в DOM.Каждый компонент Slim.js строится вокруг декларативной функции
Slim.define:
Slim.define('my-card', class extends Slim {
get template() {
return `
<div class="card">
<h2>{{title}}</h2>
<p>{{content}}</p>
</div>
`;
}
get is() {
return 'my-card';
}
onBeforeCreated() {
this.title = 'Заголовок';
this.content = 'Описание карточки';
}
});
Ключевые моменты:
get template() — возвращает
HTML-шаблон компонента. Используются двойные фигурные скобки для
биндинга свойств.get is() — уникальное имя компонента
для использования в DOM.onBeforeCreated() — жизненный цикл
компонента, позволяющий инициализировать свойства перед рендером.onCreated,
onMounted,
onUpdated, чтобы управлять поведением
компонента на разных этапах жизненного цикла.Slim.js поддерживает вложенные компоненты. Вызов дочернего компонента осуществляется простым включением его тега в шаблон родителя:
Slim.define('dashboard', class extends Slim {
get template() {
return `
<div class="dashboard">
<my-card title="Новости" content="Сегодня произошло..." />
<my-card title="События" content="Запланировано..." />
</div>
`;
}
get is() { return 'dashboard'; }
});
Глобальное состояние удобно хранить в отдельном модуле
/store/appState.js и подключать к компонентам через
подписки:
export const appState = {
user: null,
notifications: [],
subscribe(callback) {
this._callbacks = this._callbacks || [];
this._callbacks.push(callback);
},
notify() {
if (this._callbacks) {
this._callbacks.forEach(cb => cb(this));
}
}
};
Компонент может подписываться на изменения состояния в
onCreated или onMounted:
Slim.define('user-info', class extends Slim {
get template() {
return `<div>{{userName}}</div>`;
}
get is() { return 'user-info'; }
onMounted() {
appState.subscribe(state => {
this.userName = state.user ? state.user.name : 'Гость';
this.update();
});
}
});
Главный файл main.js собирает компоненты и
инициализирует их в DOM:
import './components/header.slim.js';
import './components/footer.slim.js';
import './views/home.slim.js';
document.addEventListener('DOMContentLoaded', () => {
const app = document.querySelector('#app');
app.innerHTML = `<home-page></home-page>`;
});
Такой подход позволяет сохранять четкую модульность, обеспечивая легкую замену и повторное использование компонентов без нарушения общей архитектуры.
form, layout,
widgets).Такое построение структуры обеспечивает читаемость, предсказуемость поведения и удобство поддержки при расширении функционала.