当大家在写较为复杂一点的SPA时,都会使用到路由。
前端路由有两种模式:
- Hash模式
- H5 history 模式
无论Vue的vue-router还是React的react-router,都是基于这2种模式开发的。
在对这2种路由模式进行分析前,我们先来看看一个url包含哪些部分,如果你已熟知,可以跳过此部分。
protocol :// hostname[:port] / path / [:parameters][?query]#fragment
比如:
https://localhost:8080/myapp/index.html?pageNumber=1&pageSize=10#name
location.protocol
- https:
location.hostname
- localhost
location.host
- localhost:8080
location.port
- 8080
location.pathname
- /myapp/index.html
location.search
- ?pageNumber=1&pageSize=10
location.hash
- #name
Hash 模式
通过url的hash值变化触发路由的变化,实现页面根据hash值渲染对应内容,实现路由跳转。
特点
- hash变化会触发网页跳转,即浏览器的前进、后退
- hash 变化不会刷新页面,SPA必须的特点
- hash永远不会提交到server端(完全属于前端控制)
- 实现路由跳转依赖于API window.onhashchange
下面我们来看一个demo,以及它的效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hash</title>
</head>
<body>
<H3> Change hash </H3>
<button id="update-hash-btn">Update Hash</button>
<script>
window.onhashchange = (event) => {
console.log('old url', event.oldURL);
console.log('new url', event.newURL);
console.log('current hash', location.hash);
}
document.addEventListener('DOMContentLoaded', () => {
console.log('the init hash:', location.hash);
});
document.getElementById('update-hash-btn')
.addEventListener('click', () => {
location.href = '#/profile';
});
</script>
</body>
</html>
hash
从demo中可以看出,当hash发生变化时,我们可以从onhashchange
获取到上一次的hash和当前的hash值,得到这些值后,就可以按一定的逻辑去改变页面显示的内容,显示不同的page。
H5 History模式
通过URL变化触发路由的变化,实现路由跳转,并不刷新页面,需要后端支持,通过url无法区分是前端路由还是后端路由。
在没有使用H5 history 模式的url规范路由,url每发生变化都会刷新页面,如:
https://github.com/JellyLu //刷新页面
https://github.com/JellyLu/GirlsCodingDayDemo //刷新页面
使用H5 history 模式后的url规范路由,url发生变化,不会刷新页面,只做跳转:
https://github.com/JellyLu //刷新页面
https://github.com/JellyLu/GirlsCodingDayDemo //前端跳转,不刷新页面
特点
- 用url规范的路由,但只跳转不刷新页面
- 需要后端支持
- 实现路由跳转依赖于两个重要API, history.pushState & window.onpopstate
下面我们来看一个demo,以及它的效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>H5 History</title>
</head>
<body>
<H3> Change H5 history </H3>
<button id="update-history-btn">Update History</button>
<script>
document.addEventListener('DOMContentLoaded', () => {
console.log('the init path:', location.pathname);
});
document.getElementById('update-history-btn')
.addEventListener('click', () => {
const pageName = 'profile';
const pagePath = 'profile';
const state = { name: pageName };
console.log('will navigate to', pageName);
history.pushState(state, pageName, pagePath);
});
window.onpopstate = (event) => {
console.log('onpopstate', event.state, '---path:', location.pathname);
}
</script>
</body>
</html>
h5-history
从demo中可以看出,当pathname
发生变化时,我们可以从onpopstate
获取到当前的pathname
,也可以按一定的逻辑去改变页面显示的内容,显示不同的page。
Hash vs H5 History
表现一样,url发生变化,进行路由跳转,但都不刷新页面。
实现方式不同,hash不依赖于后端,h5 history依赖于后端。
那么如何抉择使用哪种模式呢?
- to B的系统推荐使用hash,简单易用,对url规范不敏感
- to C的系统,可以考虑选择H5 history,但需要后端服务支持
当然,如果to C的系统,不需要支持搜索引擎优化(如SEO),也可以选择Hash这种简单易用的方式。
Simple is fast!
网友评论