LitRouter is a simple client side router, component loader (see PRPL) based on page.js. It's designed to work well with Web Components and LitElement.
Inspired by vue-router.
The lit-router package comes with sub package lit-page
which is a lightweight web-component that handle display of the selected route and view rendering based on the active
attribute.
To import all three classes, just import lit-router global package :
import { LitRouter } from "lit-router";
You can also only import what you need :
import { LitRouter } from "lit-router/pkg/dist-src/lit-router/lit-router.js";
import "lit-router/pkg/dist-src/lit-page/lit-page.js";
Define your routes as an Array of route Objects containing a name, a path, and a component to load (if needed).
Then call router.start();
to activate the router.
You can also define sub routes
and add route middlewares
.
import { LitRouter } from "lit-router/pkg/dist-src/lit-router/lit-router.js";
// Define your routes and the view component associated
const router = new LitRouter([
{
name: "view1",
path: "/",
component: () => import("./views/my-view1.js"), // Dynamically import component
middlewares: [
(ctx, next) => {
// Do stuff ...
next();
},
],
children: [
{
name: "subview1",
path: "/view1/detail",
component: () => import("./views/my-detail.js"),
}
]
}, {
name: "view2",
path: "/view2",
component: () => import("./views/my-view2.js")
}, {
name: "view3",
path: "/view3",
component: () => import("./views/my-view3.js")
}, {
name: "404",
path: '*',
middlewares: [
(ctx, next) => {
console.log(`Oups, I'm lost 😱 !!!`);
next();
}
]
}
]);
// Start the router
router.start();
You can define route guard with the beforeEach method like this :
router.beforeEach((route, ctx, next) => {
if (route.name == 'view2') { return document.page.redirect('/login'); }
next();
});
Once your have define your routes, you can now listen on the page-changed
event fired by the router to detect page changes.
Your can access the current matched route object via document.$router
.
The router object expose a getCurrentPage
method to retrieve the current view name.
// my-app.js
import { LitElement, html, css } from "lit-element";
// ...
class MyApp extends LitElement {
constructor() {
super();
// Add an event listener on the `page-changed` event
document.addEventListener('page-changed', () => {
const router = document.$router;
this.page = router.getCurrentPage();
});
}
static get properties() {
return {
page: String
};
}
static get styles() {
return css`
main > * {
display: none;
}
main [active] {
display: block;
}
`;
}
render() {
return html`
<main id="view">
<my-view1 name="view1" ?active="${this.page == 'view1'}"></my-view1>
<my-view2 name="view2" ?active="${this.page == 'view2'}"></my-view2>
<my-view3 name="view3" ?active="${this.page == 'view3'}"></my-view3>
</main>
`;
}
}
Import LitRouter from the lit-route ES module.
import { LitRouter } from "./lit-router.js";
Then start defining you routes by giving an array of route objects.
Route (option) :
name : The name of the route path. (this option is mandatory).
path : The path that need to be matched. (this option is mandatory).
component : This is used to load the component that need to be displayed for this route. It use dynamic import to load component. See PRPL for more information.
middlewares : An array of middleware function to be executed before the route handler. This function takes two argument, a context
object which represent the matched route, and a next
method used to pass to the next middleware or route handler.
children : An array of sub route objects.
NOTE : The child path must be the full path. e.g : /view
and /view/details
.
lit-page is a simple Web Component, that works with lit-router, that handle the display of the selected view.
Either import the whole lit-router package or just import the lit-page component.
import "lit-router/pkg/dist-src/lit-page/lit-page.js";
// my-app.js
import { LitElement, html, css } from "lit-element";
import "lit-router/pkg/dist-src/lit-page/lit-page.js";
// ...
class MyApp extends LitElement {
render() {
return html`
<lit-page>
<my-view1 name="view1" data-animation="page-enter"></my-view1>
<my-view2 name="view2"></my-view2>
<my-view3 name="view3"></my-view3>
<section name="404">
<h1>Oups, I'm lost 😱 !!!</h1>
</section>
</lit-page>
`;
}
}
attrForSelected String
= 'name'
The attrForSelected property can be used to define the selective attribute to use on view component or tags
page-changed
The page-changed event is fired when navigating to different page
LitPage provide a simple way to handle transition between pages with the data attribute data-animation
.
There is two values for this attribute :
- page-enter (default)
- page-leave