-
Notifications
You must be signed in to change notification settings - Fork 0
/
Router.js
37 lines (35 loc) · 1.37 KB
/
Router.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import NotFound from "./pages/NotFound.js";
export default class Router {
constructor({rootElement, routes, onRefresh=()=>{}}) {
this.$el = rootElement;
this.routes = [...routes].map(({ Component, ...props })=>({ component: new Component(undefined, { router: this }), ...props}));
this.fallbackComponent = new NotFound();
this.onRefresh = onRefresh;
this.currentRoute = undefined;
window.addEventListener('locationchange', event => {
this.refresh();
});
window.addEventListener('popstate', event => {
this.refresh();
});
window.addEventListener('routerLinkClick', ({ detail: route }) => {
this.push(route.name);
});
this.refresh();
}
refresh(path = window.location.pathname){
this.currentRoute = this.routes.find(el => el.path === path);
const component = this.currentRoute?.component ?? this.fallbackComponent;
if (!component) throw new Error(`no route defined for ${path}!`);
component.mount(this.$el);
this.$el = component.$el;
component.setup({ router: this });
this.onRefresh({ path, router: this });
}
push(routeName){
const route = this.routes.find(el => el.name === routeName);
history.pushState({name: route.name}, route.name, route.path);
window.dispatchEvent(new PopStateEvent('popstate'));
if (route.path !== this.currentRoute.path) this.refresh(route.path);
}
};