js路由实现
路由的基本概念
路由在JavaScript中通常指根据URL的变化动态加载不同内容或页面,而无需刷新整个页面。前端路由常见于单页应用(SPA),通过监听URL变化匹配对应组件或逻辑。
基于Hash的路由实现
Hash路由利用URL中#后的部分(即hash)实现路由切换,不会触发页面刷新。
class HashRouter {
constructor() {
this.routes = {};
window.addEventListener('hashchange', this.load.bind(this));
}
addRoute(path, callback) {
this.routes[path] = callback;
}
load() {
const hash = window.location.hash.slice(1) || '/';
const callback = this.routes[hash];
if (callback) callback();
}
}
// 使用示例
const router = new HashRouter();
router.addRoute('/', () => console.log('Home Page'));
router.addRoute('/about', () => console.log('About Page'));
基于History API的路由实现
History路由利用HTML5的history.pushState和popstate事件,可实现更干净的URL(无#)。
class HistoryRouter {
constructor() {
this.routes = {};
window.addEventListener('popstate', this.load.bind(this));
}
addRoute(path, callback) {
this.routes[path] = callback;
}
navigate(path) {
history.pushState({}, '', path);
this.load();
}
load() {
const path = window.location.pathname;
const callback = this.routes[path];
if (callback) callback();
}
}
// 使用示例
const router = new HistoryRouter();
router.addRoute('/', () => console.log('Home Page'));
router.addRoute('/about', () => console.log('About Page'));
router.navigate('/about'); // 手动导航
动态路由匹配
支持参数化路由,如/user/:id。
class DynamicRouter {
constructor() {
this.routes = [];
window.addEventListener('popstate', this.load.bind(this));
}
addRoute(path, callback) {
const paramsKeys = [];
const regex = path.replace(/:(\w+)/g, (_, key) => {
paramsKeys.push(key);
return '([^/]+)';
});
this.routes.push({
regex: new RegExp(`^${regex}$`),
callback,
paramsKeys
});
}
load() {
const path = window.location.pathname;
for (const route of this.routes) {
const match = path.match(route.regex);
if (match) {
const params = {};
route.paramsKeys.forEach((key, i) => {
params[key] = match[i + 1];
});
route.callback(params);
break;
}
}
}
}
// 使用示例
const router = new DynamicRouter();
router.addRoute('/user/:id', (params) => {
console.log(`User ID: ${params.id}`);
});
路由库的使用
实际项目中通常使用成熟的路由库,如React Router或Vue Router。
React Router示例:
import { BrowserRouter, Route, Link } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</BrowserRouter>
);
}
Vue Router示例:
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About }
];
const router = new VueRouter({
routes
});
new Vue({
router
}).$mount('#app');
路由守卫实现
控制路由跳转前后的权限校验或逻辑处理。

class GuardedRouter extends HistoryRouter {
constructor() {
super();
this.beforeHooks = [];
this.afterHooks = [];
}
beforeEach(callback) {
this.beforeHooks.push(callback);
}
afterEach(callback) {
this.afterHooks.push(callback);
}
navigate(path) {
const runHooks = (hooks, args, index = 0) => {
if (index >= hooks.length) return Promise.resolve();
return hooks[index](...args).then(() => runHooks(hooks, args, index + 1));
};
runHooks(this.beforeHooks, [path])
.then(() => {
history.pushState({}, '', path);
this.load();
runHooks(this.afterHooks, [path]);
});
}
}
// 使用示例
const router = new GuardedRouter();
router.beforeEach((path) => {
console.log(`Navigating to ${path}`);
return Promise.resolve();
});
以上实现方案覆盖了从基础路由到高级功能的完整链路,可根据实际需求选择适合的方案或组合使用。






