Slim.js предоставляет минималистичный, компонентно-ориентированный подход к разработке веб-приложений. Его встроенный роутинг подходит для большинства задач, однако для сложных приложений часто требуется интеграция сторонних роутеров, таких как Navigo, Page.js или Director. Slim.js не накладывает жестких ограничений, что позволяет гибко сочетать внутренние компоненты и внешние маршрутизаторы.
В Slim.js компоненты могут управлять своим состоянием и визуализацией независимо, но маршрутизация обычно осуществляется через глобальные события или через управление состоянием приложения. Основные моменты:
Для интеграции стороннего роутера важно создать прослойку, которая синхронизирует маршруты внешнего роутера с состоянием Slim.js. Рассмотрим пример с Navigo:
import Navigo from 'navigo';
import { Slim } from 'slim-js';
const router = new Navigo('/', { hash: true });
class AppComponent extends Slim {
get useShadow() {
return true;
}
template() {
return `
<div id="view"></div>
`;
}
onRouteChange(viewName) {
this.shadowRoot.getElementById('view').innerHTML = `<${viewName}></${viewName}>`;
}
}
const app = new AppComponent();
document.body.appendChild(app);
// Настройка маршрутов
router.on({
'/home': () => app.onRouteChange('home-component'),
'/about': () => app.onRouteChange('about-component'),
'/contact': () => app.onRouteChange('contact-component')
}).resolve();
Ключевые моменты интеграции:
Для маршрутов с параметрами, таких как /user/:id,
требуется передача параметров внутрь компонентов. В Navigo это выглядит
так:
router.on('/user/:id', (params) => {
app.onRouteChange('user-component', params.id);
});
В Slim.js:
class UserComponent extends Slim {
set userId(id) {
this._userId = id;
this.renderUser();
}
renderUser() {
this.innerHTML = `<p>Пользователь с ID: ${this._userId}</p>`;
}
}
Такой подход позволяет динамически подставлять данные в компоненты при смене маршрута, сохраняя реактивность Slim.js.
В больших приложениях часто необходимо синхронизировать состояние между роутером и другими компонентами:
setState или пользовательских методов для обновления
интерфейса.Пример:
class AppState {
constructor() {
this.currentRoute = '';
this.listeners = [];
}
setRoute(route) {
this.currentRoute = route;
this.listeners.forEach(cb => cb(route));
}
subscribe(cb) {
this.listeners.push(cb);
}
}
const appState = new AppState();
router.on({
'/home': () => appState.setRoute('home-component'),
'/about': () => appState.setRoute('about-component')
});
appState.subscribe((route) => {
app.onRouteChange(route);
});
В проектах с микрофронтендами может понадобиться использование нескольких роутеров одновременно. В Slim.js это реализуется через делегирование маршрутов:
/admin/*,
/user/*).Пример делегирования:
adminRouter.on('/admin/:page', (params) => app.onRouteChange('admin-component', params.page));
userRouter.on('/user/:id', (params) => app.onRouteChange('user-component', params.id));
Для плавной навигации рекомендуется:
router.navigate() или аналогичные
для программной смены маршрута.window.location, чтобы не
ломать реактивность компонентов.Slim.js с внешними роутерами позволяет реализовать серверный рендеринг и SEO-оптимизацию через:
pushState.Пример динамического обновления заголовка:
appState.subscribe((route) => {
document.title = `Страница - ${route.replace('-component', '')}`;
});
hash и pushState.Интеграция сторонних роутеров в Slim.js обеспечивает мощную гибкость, позволяя строить масштабируемые SPA с минимальными ограничениями и поддержкой сложных сценариев маршрутизации.