Конфигурация маршрутов

Mithril предоставляет встроенный роутер, который обеспечивает управление состоянием приложения и навигацию между различными представлениями. Конфигурация маршрутов осуществляется через объект m.route, который связывает URL-пути с компонентами или функциями обработки.

Инициализация маршрутов

Для настройки маршрутов используется метод m.route(). Основная сигнатура выглядит следующим образом:

m.route(root, defaultRoute, routes);
  • root — DOM-элемент, в котором будет отрисовываться текущее представление. Обычно это <div> с уникальным id.
  • defaultRoute — путь по умолчанию, на который будет перенаправлен пользователь при загрузке приложения.
  • routes — объект, где ключи — URL-пути, а значения — компоненты или объекты с дополнительными настройками маршрута.

Пример базовой конфигурации:

m.route(document.getElementById('app'), '/home', {
    '/home': HomeComponent,
    '/about': AboutComponent,
    '/contact': ContactComponent
});

Маршруты с параметрами

Mithril позволяет определять динамические сегменты в маршрутах. Такие сегменты обозначаются двоеточием (:) перед именем параметра.

m.route(document.getElementById('app'), '/user/1', {
    '/user/:id': UserComponent
});

Внутри компонента параметр можно получить через vnode.attrs:

const UserComponent = {
    view: function(vnode) {
        return m('div', `ID пользователя: ${vnode.attrs.id}`);
    }
};

Использование редиректов

Иногда необходимо перенаправлять пользователя с одного маршрута на другой. Для этого в компоненте можно вызвать:

m.route.set('/new-path');

Это моментально изменяет URL и инициирует перерисовку соответствующего компонента.

Асинхронная загрузка компонентов

Mithril поддерживает ленивую загрузку компонентов через функции, возвращающие промис. Это полезно для разделения кода и уменьшения начального размера бандла.

m.route(document.getElementById('app'), '/home', {
    '/home': () => import('./HomeComponent.js'),
    '/about': () => import('./AboutComponent.js')
});

При использовании асинхронных компонентов роутер автоматически обрабатывает промис и отображает компонент после загрузки.

Объекты маршрутов с жизненным циклом

Маршруты можно задавать не только через компонент, но и через объект, включающий методы жизненного цикла, например onmatch и render.

  • onmatch(args, requestedPath) — вызывается перед рендером компонента. Можно возвращать промис для асинхронной загрузки или выполнять проверку доступа.
  • render(vnode) — позволяет кастомизировать процесс рендеринга компонента.

Пример:

m.route(document.getElementById('app'), '/dashboard', {
    '/dashboard': {
        onmatch: function(args, requestedPath) {
            if (!isLoggedIn()) {
                return m.route.set('/login');
            }
            return DashboardComponent;
        },
        render: function(vnode) {
            return m('div.wrapper', m('h1', 'Панель управления'), m(vnode.tag));
        }
    }
});

Настройка базового пути

Для приложений, развернутых не в корне сайта, можно задать базовый путь через m.route.prefix:

m.route.prefix('/app');

После этого все маршруты будут работать относительно указанного префикса.

Навигация без перезагрузки страницы

Mithril использует History API для управления навигацией, что обеспечивает изменение URL без полной перезагрузки страницы. Это делает приложения быстрыми и отзывчивыми. Прямое изменение window.location для перехода между маршрутами не требуется и даже может вызвать нежелательное поведение.

Защита маршрутов

С помощью onmatch легко реализовать защиту маршрутов, проверку авторизации и редиректы. Асинхронные проверки позволяют обращаться к серверу перед загрузкой компонента, предотвращая рендер нежелательных страниц.

'/profile': {
    onmatch: async function() {
        const isAuthenticated = await checkAuth();
        return isAuthenticated ? ProfileComponent : m.route.set('/login');
    }
}

Глубокая интеграция с компонентами

Маршруты можно комбинировать с дочерними компонентами и состоянием приложения. Например, при построении SPA с панелью навигации и контентом:

const Layout = {
    view: function(vnode) {
        return m('div', [
            m(Navbar),
            m('main', vnode.children)
        ]);
    }
};

m.route(document.getElementById('app'), '/home', {
    '/home': { render: () => m(Layout, m(HomeComponent)) },
    '/about': { render: () => m(Layout, m(AboutComponent)) }
});

Это позволяет создавать единый макет с динамическим содержимым.

События маршрутизатора

Mithril предоставляет возможность реагировать на изменение маршрута через события m.route.get(). Это удобно для синхронизации состояния приложения с текущим URL:

const currentRoute = m.route.get();
console.log('Текущий маршрут:', currentRoute);

Используя эти механизмы, можно реализовать полноценную систему маршрутизации, поддерживающую параметры, ленивую загрузку, защиту маршрутов и кастомный рендеринг, обеспечивая при этом высокую производительность и отзывчивость интерфейса.