前端路由与单页页面实践 原创 精华
作者:李行杨
路由就是指随着浏览器地址栏的变化,展示给用户的页面也不相同。
传统的网页根据用户访问的不同的地址,浏览器从服务器获取对应页面的内容展示给用户。这样容易造成服务器压力比较大,而且用户访问速度也比较慢,在这种场景下,出现了单页应用。
路由的实现方式
- location.hash+hashchange事件
- history.pushState()+popState事件
实现主要基于以下几个方面的特性
- URL 中的 hash 值只是客户端的一种状态,也就是说当向服务器发出请求时,hash 部分不会被发送
- hash 值的改变,都会在浏览器的访问历史中增加一个记录,因此我们能通过浏览器的回退,前进按钮控制 hash 的切换
- 可以通过设置a标签,并通过设置 href 属性,例如href = ‘#/blue’,当点击标签的时候,url的 hash 值会发生改变,在当前url的后面增加上’#/blue’, 同时触发hashchange,再回调函数中进行处理
- 前进后退的时候,可以直接通过js来对 location.hash 进行赋值,改变url的 hash 值,例如 location.hash = ‘#/blue’即可,此时url会改变, 也会触发hashchange事件。
- 因此我们可以使用 hashchange 事件来监听 hash 值得变化,从而对页面进行跳转(渲染)
hash模式
hash方法是在路由中带有一个#,主要原理是通过监听#后的 URL 路径标识符的更改而触发的浏览器hashchange事件,然后通过获取location.hash 得到当前的路径标识符,再进行一些路由跳转的操作。hash方法的push本身会记录你的点击记录,当你想要通过返回按钮返回时,它会根据你的点击记录用到replace来解决。
hash路由 | 优点 | 缺点 |
---|---|---|
通过监听url中的hash变化来进行路由跳转当hash发生变化时,浏览器更新视图并不会重新发起请求,而是会触发 hashchange事件 | 浏览器兼容性较好,连IE8 都支持 | 路径在井号 # 的后面,比较丑,问题在于url中一直存在#不够美观而且hash路由更像是hack而非标准,相信随着发展更加标准化的history API会逐步蚕食掉hash路由的市场 |
- 先建立一个index.html文件,在body标签中开始hash的编写:
- 然后引用js文件处理router里面的逻辑
history模式
HistoryAPI来实现URL的变化,其中最主要用history.pushState()新增一个历史记录,用history.replaceState()直接替换当前历史记录,可以在不进行刷新的情况下,操作浏览器的历史记录。需要后台配置支持,因为我们的应用是个单页的客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问一些没有配置的路径就会返回404,但因为没有#号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要定向到根路径。html5 提供了historyAPI来实现URL的变化,其中最主要的 API 有以下两个:
-
history.pushState()新增一个历史记录。
-
history.replaceState() 直接替换当前历史记录。
相同点:可以在不进行刷新的情况下,操作浏览器的历史记录。 -
先建立一个index.html文件,在body标签中开始history的编写:
- 然后引用js文件处理router里面的逻辑
总结
本文讲解了路由的核心实现原理,但是结合具体框架后,框架增加了很多特性,如动态路由、路由参数、路由动画等等,这些导致路由实现变的复杂。本文去粗取精只针对前端路由最核心部分的实现进行分析,并基于 hash 和 history 两种模式,页面加载时,它可能有一个非空状态对象。例如,如果页面设置了一个状态对象(使用pushState()or replaceState())然后用户重新启动他们的浏览器,当页面重新加载时,页面将收到一个onload事件,虽没有popstate事件,但是将获得加载的状态对象。
到这里就结束啦,希望通过阅读本文有所收获,如有错误,欢迎指出,感谢阅读。
更多原创内容请关注:中软国际 HarmonyOS 技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
赞,必须好好学习一波