1.前端路由出现的背景
路由最早出现在后端,也就是服务器端的路由,对于服务器来说,当接收到客户端发来的HTTP请求,就会根据所请求的相应URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,可以认为,所有URL的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理,等等。然后根据这些读取的数据,在服务器端就使用相应的模板来对页面进行渲染后,再返回渲染完毕的页面。
但是如果由服务端进行路由,会加重服务端的负担,不利于用户体验。
另外,近几年出现的SPA(单页应用),大大提高了 WEB 应用的交互体验。在与用户的交互过程中,不再需要重新刷新页面,获取数据也是通过 Ajax 异步获取,页面显示变的更加流畅。但是它的缺点也很明显,不利于Seo, 也无法记住用户的操作记录,无论是刷新、前进还是后退,都无法展示用户真实的期望内容。
为了缓解服务端处理压力,解决SPA出现的问题,前端路由应运而生。
2.前端路由的两种实现方案
-
Hash模式
主要是基于location.hash来实现的,这里的 hash 就是指 url 后的 # 号以及后面的字符。比如说 “www.baidu.com/#hashhash” ,其中 “#hashhash” 就是我们期望的 hash 值。window对象提供了onhashchange事件来监听hash值的改变,一旦url中的hash值发生改变,便会触发该事件,达到路由切换的目的。触发hsah变化的方式主要有两种,一种是通过a标签,并设置href属性,当用户点击这个标签后,URL就会发生改变,触发hashchange事件;还有一种方式就是直接使用JavaScript来对loaction.hash进行赋值,从而改变URL,触发hashchange事件。
使用hash模式时,我们可以考虑对每个路由注册一个映射函数,页面加载时,在window注册onhashchange事件的监听函数,每次切换url,就调用对应的映射函数,根据上面的思路,可以实现一个class,包含注册和切换的监听函数:
export default class HashRouter{
constructor(){
this.routers = {}
window.addEventListener('hashchange',this.load.bind(this),false)
}
register(hash, callback){
this.routers[hash] = callback
}