前端路由
前置知识
- 对象:
location、history; - 事件:
popstate、hashchange - 作为前端路由,路由操作一定不能刷新页面,这一点很重要!
hash 路由
原理
修改 location.hash 值(页面不会刷新),如果修改前后值不一致,则往 history 中增加一条记录;当 hash 值改变时会触发 hashchange 事件,此时便可以进行一些 dom 操作。
代码
class HashRouter {
constructor(options) {
// 保存路由信息
this.routes = options.routes;
// 监听 hash 值
window.addEventListener('hashchange', this.render.bind(this));
// 页面加载完成
window.addEventListener('load', this.load.bind(this));
}
load() {
// 使用 vue-router 中的标签
this.view = document.querySelector('router-view');
this.links = document.querySelectorAll('router-link');
this.links.forEach(item => item.addEventListener('click', () => this.push(item.getAttribute('to'))));
}
// 路由
push(path) {
location.hash = path;
}
// 获取当前路径
getPath() {
return location.hash.replace(/^#/, '') || '/';
}
// 获取当前路由
getRoute() {
const path = this.getPath();
return this.routes.find(route => route.path === path);
}
// 渲染
render() {
const route = this.getRoute();
this.view.innerHTML = route?.component;
}
}
history 路由
原理
使用 history.pushState 或 history.replaceState 往 history 中添加一条记录(不会刷新页面),可以进行一些 dom 操作;当使用前进和后退功能时(添加时不刷新页面,前进与后退也不会刷新页面),会触发 popState 事件,此时可以进行一些 dom 操作。
代码
class HistoryRouter {
constructor(options) {
this.routes = options.routes;
window.addEventListener('popstate', this.render.bind(this));
window.addEventListener('load', this.load.bind(this));
}
load() {
this.view = document.querySelector('router-view');
this.links = document.querySelectorAll('router-link');
this.links.forEach(item => item.addEventListener('click', () => this.push(item.getAttribute('to'))));
this.render();
}
push(path) {
history.pushState(null, null, path);
this.render();
}
getPath() {
return location.pathname;
}
getRoute() {
const path = this.getPath();
return this.routes.find(route => route.path === path);
}
render() {
const route = this.getRoute();
this.view.innerHTML = route?.component;
}
}
以上只是给出大体思路,实际还有许多问题要处理。

浙公网安备 33010602011771号