面试复习-js路由原理
参考链接
https://www.cnblogs.com/tugenhua0707/p/10859214.html
https://www.jianshu.com/p/4295aec31302
为什么会有前端路由
后端路由有一个很大的缺点就是每次路由切换的时候都需要去刷新页面,然后发出ajax请求,然后将请求数据返回回来,那么这样每次路由切换都要刷新页面对于用户体验来说就不好了。因此为了提升用户体验,我们前端路由就这样产生了。它就可以解决浏览器不会重新刷新了。
Hash模式
hash路由模式是这样的:http://xxx.abc.com/#/xx。 有带#号,后面就是hash值的变化。**改变后面的hash值,它不会向服务器发出请求,因此也就不会刷新页面。**并且每次hash值发生改变的时候,会触发hashchange事件。因此我们可以通过监听该事件,来知道hash值发生了哪些变化。
function hashAndUpdate () {
// todo 匹配 hash 做 dom 更新操作
}
window.addEventListener('hashchange', hashAndUpdate);
属性 | 描述 |
---|---|
location.href | 完整的url |
location.protocol | 当前URL的协议,包括 :; 比如 https: |
location.host | 主机名和端口号,如果端口号是80(http)或443(https), 那就会省略端口号,比如www.baidu.com:8080 |
location.hostname | 主机名:比如:www.baidu.com |
location.port | 端口号;比如8080 |
location.pathname | url的路径部分,从 / 开始; 比如 https://www.baidu.com/s?ie=utf-8,那么 pathname = '/s’了 |
location.search | 查询参数,从?开始;比如 https://www.baidu.com/s?ie=utf-8 那么 search = ‘?ie=utf-8’ |
location.hash | hash是页面中的一个片段,从 # 开始的,比如 https://www.baidu.com/#/a/b 那么返回值就是:"#/a/b |
修改hash值会触发hashchange方法,并且不会刷新页面。
可以把hash理解成当前页面的一个位置。
History模式
HTML5的History API为浏览器的全局history对象增加了该扩展方法。它是一个浏览器的一个接口,在window对象中提供了onpopstate事件来监听历史栈的改变,只要历史栈有信息发生改变的话,就会触发该事件。提供了如下事件:
API | 描述 |
---|---|
window.history.length: | 返回当前会话浏览过的页面数量。 |
window.history.go(?delta) | 接收一个整数作为参数,按照当前页面在会话浏览历史记录中的位置进行移动。如果参数为0、undefined、null、false 将刷新页面,相当于执行window.location.reload()方法。如果参数大于浏览器浏览的数量,或小于浏览前的数量的话,什么都不会做。 |
window.history.back() | 移动到上一页。相当于点击浏览器的后退按钮,等价于 window.history.go(-1); |
window.history.forward() | 移动到下一页,相当于点击浏览器的前进按钮,等价于window.history.go(1). |
window.history.pushState(data, title, ?url): | 在会话浏览历史记录中添加一条记录。 |
window.history.replaceState(data, title, ?url) | 该方法用法和history.pushState方法类似,但是该方法的含义是将修改会话浏览历史的当前记录,而不是新增一条记录。也就是说把当前的浏览地址换成 replaceState之后的地址,但是浏览历史记录的总长度并没有新增。 |
注意:执行后两种方法后,url地址会发生改变。但是不会刷新页面。
window.addEventListener('popstate', function(e) {
console.log(e)
});
Hash模式和History模式的比较
相同点:
- 不管我们是通过location接口直接改变hash值,还是我们通过history直接前进或后退操作(改变hash变化),都不会刷新页面。
- 改变hash或history时都可以触发hashchange事件或者popstate事件
不同点:
- hash改变时其#后面的值不会传给后端。而history会修改当前页面的url。
- pushState设置的新URL可以是与当前URL同源的任意URL;而hash只可修改#后面的部分,故只可设置与当前同文档的URL
- pushState通过stateObject可以添加任意类型的数据到记录中;而hash只可添加短字符串。
- pushState可额外设置title属性供后续使用。
- history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误
Vue中的router
- $router.push()
1 $router.push() //调用方法
2 HashHistory.push()
//根据hash模式调用,设置hash并添加到浏览器历史记录(添加到栈顶)
(window.location.hash= XXX)
3 History.transitionTo()
//监测更新,更新则调用History.updateRoute()
4 History.updateRoute()
//更新路由
5 {app._route= route}
//替换当前app路由
6 vm.render()
//更新视图
- $router.replace()
与push不同之处主要在于第二步调用的是window.location.replace方法