前端单页面路由(SPA 路由)的核心原理是通过拦截浏览器的 URL 变化并动态加载对应的页面内容,而不重新加载整个页面。它依赖于浏览器的特性,如 Hash 和 History API,实现页面导航与视图更新分离。
实现单页面路由的两种主要模式
1. 基于 Hash 的路由
-
URL 格式:
example.com/#/home -
原理:
#后的内容(称为 hash)不会被发送到服务器,仅在浏览器端可见。- 通过监听
window.onhashchange事件捕获 hash 的变化。
-
优点:
- 无需服务器配置即可运行。
- 实现简单,兼容性好。
-
缺点:
- URL 不够美观。
- 不支持 SEO。
// 简单的 Hash 路由实现
const routes = {
'/home': '<h1>Home</h1>',
'/about': '<h1>About</h1>',
'/contact': '<h1>Contact</h1>',
};
function render() {
const hash = location.hash.slice(1); // 获取 # 之后的路径
const app = document.getElementById('app');
app.innerHTML = routes[hash] || '<h1>404 Not Found</h1>';
}
window.addEventListener('hashchange', render);
window.addEventListener('load', render);
2. 基于 History 的路由
-
URL 格式:
example.com/home -
原理:
- 利用 HTML5 的
History API(如pushState和replaceState)手动操作浏览器历史记录。 - 通过监听
popstate事件检测历史记录变化。
- 利用 HTML5 的
-
优点:
- URL 直观美观。
- 更接近传统的多页面应用 URL,支持 SEO。
-
缺点:
- 需要服务器配置,否则直接访问子路由可能导致 404。
- 实现复杂度较高。
// 简单的 History 路由实现
const routes = {
'/home': '<h1>Home</h1>',
'/about': '<h1>About</h1>',
'/contact': '<h1>Contact</h1>',
};
function render() {
const path = window.location.pathname; // 获取路径
const app = document.getElementById('app');
app.innerHTML = routes[path] || '<h1>404 Not Found</h1>';
}
function navigate(event) {
event.preventDefault(); // 阻止默认跳转
const url = event.target.getAttribute('href');
history.pushState(null, '', url); // 更新浏览器历史记录
render();
}
document.addEventListener('click', (event) => {
if (event.target.matches('[data-link]')) {
navigate(event);
}
});
window.addEventListener('popstate', render);
window.addEventListener('load', render);
总结
不同模式适用于不同的应用场景:如果是简单项目或无需 SEO,Hash 模式是更轻便的选择;如果是复杂项目或需要支持 SEO,则优先选择 History 模式。
推荐阅读相关文章: