前言
在现代 web 开发中,单页面应用(SPA)已经成为了一种不可或缺的模式,而前端路由则是其背后的核心驱动力。想象一下,如果没有前端路由,用户在浏览你的网站时,每次点击链接都必须重新加载整个页面,那将会是怎样一种体验?页面闪烁、等待加载、丧失了流畅感——用户的耐心瞬间耗尽,留不住访客的可能性骤然增加。
前端路由通过在不刷新页面的情况下根据 URL 的变化动态加载内容,让用户能够无缝地探索应用的不同部分。这不仅提升了用户体验,还大幅度提高了应用的性能和响应速度。它就像是一个无形的桥梁,让用户在信息的海洋中尽情游历。
前端路由主要依靠两种技术:hash
和 history
。这两者使得我们能够在改变 URL 的同时,确保页面的状态保持不变、体验依然流畅。尤其是在移动设备普及的今天,加载速度和用户体验变得尤为重要。
综上所述,前端路由不仅仅是一个技术细节,而是现代 web 开发中提升用户体验、增强应用性能的重要工具。对于想要在激烈竞争中脱颖而出的开发者来说,熟练掌握前端路由的运作原理,将为你的项目成功奠定坚实的基础。
而今天我来从hash
技术原理出发,探讨前端路由的实现过程。
正文
1. 路由基础
在讲之前,我们先了解一点路由基础:
在传统的多页面应用(MPA)中,每当用户点击一个链接时,浏览器会重新加载页面,并根据服务器返回的内容渲染新的视图。而在 SPA 中,前端路由则承担了不同视图的切换任务。前端路由的核心就是根据 URL 地址的变化,动态地加载相应的组件,而不刷新整个页面。简单来说,我们想实现前端路由只需要解决以下两个问题:
- 如何修改 URL,而不引起页面刷新
- 如何检测 URL 变化
2. Hash 路由
然后我们再来简单了解一下Hash路由。
Hash 路由是最早实现前端路由的方式,它通过修改 URL 中的 #
符号后的部分来表示不同的路由。#
后的内容并不会被发送到服务器,因此修改它不会导致页面的重新加载,浏览器也不会重新发送 HTTP 请求。
也就是在浏览器url后拼接 #xxxx 会被认为是hash值,而hash值的变更是不会引起浏览器页面的刷新。
正如这图中一样,url地址后面加#aaaaaaaaaaa并不会引起浏览器页面的刷新。
代码部分
话不多说,我们直接代码展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li><a href="#/home">首页</a></li>
<li><a href="#/about">关于</a></li>
</ul>
<div id="routeView">
<!-- 放一个代码片段 -->
</div>
<script>
const routes = [
{
path: '#/home',
component: '首页页面内容',
},
{
path: '#/about',
component: 'about page'
}
]
const routeView = document.getElementById('routeView')
window.addEventListener('DOMContentLoaded',onHashChange)
window.addEventListener('hashchange', onHashChange)
function onHashChange() {
console.log(location.hash);
routes.forEach((item, index) => {
if(item.path === location.hash) {
routeView.innerHTML = item.component
}
})
}
</script>
</body>
</html>
代码讲解
我这段代码展示了一个简单的基于 Hash 路由 的前端路由实现。它通过监听 URL 中 hash
值的变化,动态切换不同的页面内容,而无需重新加载整个页面。接下来我会给各位详细讲解一下。
核心原理
-
URL 中的 Hash (
#
) 使用:- 在浏览器 URL 中,
#
后面的部分被称为 hash 值,不会被发送到服务器,而仅由浏览器解析。 - 修改 hash 值不会引起页面的刷新,因此它成为前端路由实现的一种简便方式。
- 在浏览器 URL 中,
-
事件监听:
hashchange
事件:就是当 URL 中的 hash 部分发生变化时,也就是#后面的值变化,会触发hashchange
事件。代码中的window.addEventListener('hashchange', onHashChange)
监听了这一事件。DOMContentLoaded
事件:就是当初始页面加载完成后,触发DOMContentLoaded
事件,确保页面加载时也会执行一次onHashChange()
,显示正确的初始内容。
-
路由匹配逻辑:
- 在
onHashChange
函数中,通过遍历定义的routes
数组,检查当前location.hash
是否与某个路由的path
匹配。 - 如果匹配成功,将对应的
component
内容插入到routeView
容器中,实现页面的动态内容切换。
- 在
详细代码解析
-
HTML 结构:
<ul> <li><a href="#/home">首页</a></li> <li><a href="#/about">关于</a></li> </ul> <div id="routeView"></div>
- 导航链接:点击
<a>
标签时,URL 的 hash 值会改变,比如点击“首页”会将 URL 修改为http://baidu.com/#/home
。 routeView
容器:用于展示当前路由对应的组件内容。
- 导航链接:点击
-
JavaScript 路由逻辑:
const routes = [ { path: '#/home', component: '首页页面内容' }, { path: '#/about', component: 'about page' } ]; const routeView = document.getElementById('routeView'); window.addEventListener('DOMContentLoaded', onHashChange); window.addEventListener('hashchange', onHashChange); function onHashChange() { console.log(location.hash); routes.forEach((item) => { if (item.path === location.hash) { routeView.innerHTML = item.component; } }); }
-
routes
数组:定义了路由规则,每个路由对象包含:path
:URL 中的 hash 路径(如#/home
)。component
:与该路径匹配时要显示的内容。
-
事件监听设置:
DOMContentLoaded
监听器:确保页面加载完成时执行一次路由匹配,显示正确的初始内容。hashchange
监听器:当用户通过点击链接或使用浏览器的前进/后退按钮改变 hash 时,会触发该事件。
-
onHashChange
函数:- 获取当前的 hash 值并与
routes
中定义的路径进行比对。 - 如果找到匹配的路径,将对应的
component
内容渲染到routeView
容器中。
- 获取当前的 hash 值并与
-
而我们前文说过,实现前端路由原理需要解决的两个问题是:
1.如何修改 URL,而不引起页面刷新,
2.如何检测 URL 变化。现在看来是不是都解决了,在url后面加#解决第一个问题,hashchange事件解决第二个问题,到这就基本解决了前端路由原理问题,当然我这里只是讲最基本的东西,前端路由原理肯定不止这些,这就不多讲。我再解释一下代码里的location.hash
,它 是 JavaScript 中 Location
对象的一个属性,它返回当前 URL 中井号(#
)之后的部分。routeView.innerHTML = item.component;
这一行代码的作用是将 DOM 元素 routeView
的 HTML 内容更新为 item.component
的值。以防有小伙伴不懂。
前端路由原理体现
-
无页面刷新机制:
- 修改 hash 值不会导致页面重新加载,这样就可以在同一个 HTML 文档中实现不同视图之间的切换。
hashchange
事件确保了内容的更新仅限于routeView
容器内,而不是重新渲染整个页面。
-
路由映射机制:
- 通过维护一个
routes
数组,将 URL 路径与页面内容或组件进行映射。 - URL 改变触发
onHashChange
,实现从 URL 到组件的动态映射。
- 通过维护一个
-
用户体验优化:
- URL 的变化反映了用户当前所在的页面状态,用户可以使用浏览器的前进和后退按钮在不同视图间切换,而不会丢失当前状态。
这段代码充分体现了基于 Hash 路由 的核心机制:通过监听 hash 值的变化,动态渲染不同的内容,从而实现前端页面的无刷新切换。这种方法简单易用,非常适合构建小型单页面应用。
小结
前端路由的核心在于修改 URL 而不刷新页面,从而实现单页面应用的流畅体验。hash
路由简单易用,但在 URL 设计上有一定的局限;而 history
路由则提供了更加灵活和优雅的解决方案,适合复杂的 SPA 项目。而这里我们只讲了hash
路由,在下篇文章我会给大家讲讲history
路由,觉得有帮助的伙伴点点赞和关注。