Mithril предоставляет мощный и лаконичный механизм для маршрутизации, который позволяет строить как простые, так и сложные одностраничные приложения. Важной особенностью является возможность вложенной маршрутизации, когда один маршрут содержит дочерние маршруты, что позволяет организовывать интерфейс и логику приложения по модульному принципу.
В Mithril маршруты настраиваются с помощью объекта
m.route. Основной синтаксис:
m.route(root, defaultRoute, {
"/home": HomeComponent,
"/about": AboutComponent
});
root — корневой DOM-элемент приложения.defaultRoute — маршрут, на который будет перенаправлен
пользователь при загрузке.Каждый компонент маршрута должен реализовывать либо метод
view, либо возвращать функцию, генерирующую
виртуальный DOM.
Вложенные маршруты позволяют определить маршруты внутри компонентов, которые сами уже привязаны к внешнему маршруту. Это особенно полезно для страниц с разделами или вкладками.
Пример структуры:
/dashboard
/dashboard/profile
/dashboard/settings
Здесь /dashboard является родительским маршрутом, а
/dashboard/profile и /dashboard/settings —
дочерними. Родительский компонент управляет общим интерфейсом, например,
боковой панелью, а дочерние компоненты подставляются в область
контента.
Для вложенной маршрутизации создаётся отдельный внутренний
m.route в компоненте родителя. Пример:
const Dashboard = {
view: () => m("div", [
m("nav", [
m("a[href='/dashboard/profile']", { oncreate: m.route.link }, "Profile"),
m("a[href='/dashboard/settings']", { oncreate: m.route.link }, "Settings")
]),
m("div#dashboard-content") // контейнер для дочерних маршрутов
]),
oncreate: () => {
m.route(document.getElementById("dashboard-content"), "/dashboard/profile", {
"/dashboard/profile": Profile,
"/dashboard/settings": Settings
});
}
};
Особенности:
m.route инициализируется в методе
oncreate родительского компонента.div#dashboard-content)
становится корнем для внутренней маршрутизации.m.route.link гарантирует корректное
обновление URL без перезагрузки страницы.Вложенные маршруты могут использовать динамические параметры, например идентификаторы:
m.route(document.getElementById("dashboard-content"), "/dashboard/user/1", {
"/dashboard/user/:id": UserDetail
});
Компонент UserDetail получает параметр id
через объект vnode.attrs:
const UserDetail = {
view: (vnode) => m("div", `Пользователь ID: ${vnode.attrs.id}`)
};
Это позволяет создавать страницы профилей, заказов или других сущностей с уникальными идентификаторами.
Для перехода между родительскими и дочерними маршрутами используется
стандартная функция m.route.set:
m.route.set("/dashboard/settings");
При этом состояние родительского компонента сохраняется, а дочерний компонент обновляется в пределах контейнера.
Вложенная маршрутизация упрощает модульное построение приложения:
import() позволяет оптимизировать размер бандла.Пример с ленивой загрузкой:
m.route(document.getElementById("dashboard-content"), "/dashboard/profile", {
"/dashboard/profile": () => import("./Profile.js"),
"/dashboard/settings": () => import("./Settings.js")
});
m.route не сможет привязать дочерние маршруты.const App = {
view: () => m("div", m("div#app-content"))
};
const Dashboard = {
view: () => m("div", [
m("h2", "Панель управления"),
m("nav", [
m("a[href='/dashboard/profile']", { oncreate: m.route.link }, "Profile"),
m("a[href='/dashboard/settings']", { oncreate: m.route.link }, "Settings")
]),
m("div#dashboard-content")
]),
oncreate: () => {
m.route(document.getElementById("dashboard-content"), "/dashboard/profile", {
"/dashboard/profile": Profile,
"/dashboard/settings": Settings
});
}
};
m.route(document.getElementById("app-content"), "/dashboard", {
"/dashboard": Dashboard
});
В этой конструкции создаётся иерархия маршрутов, позволяющая масштабировать приложение без перегруженности кода и потери управляемости интерфейсом.
Вложенная маршрутизация в Mithril обеспечивает гибкость при построении сложных интерфейсов, сочетая лаконичность синтаксиса и точный контроль за отображением компонентов на разных уровнях URL.