vue-router实现原理的概述
vue-router实现了再不跳转页面的情况下更新视图,也就是只有一个页面。
对比我们学过的a标签,它的href属性设置了一个地址,我们点击a标签就会跳转到链接的网址,和我们的vue-router就是不一样的。
在浏览器环境下,vue-router有两种模式:history模式和hash模式
hash模式
hash 模式概述
hash模式需要注意以下三点:
- hash模式实现的路由地址有 #
- #后面的内容不会传给服务端,也就是说不会重新刷新页面,并且路由切换的时候也不会重新加载页面。
- hash必须和原先的值不同,才能新增会话浏览历史的记录。
一个简单的例子观察一下hash 模式的地址栏:
hash模式底层实现原理
<body>
<a href="#/login">登录</a>
<a href="#/desk">桌面</a>
<hr>
<div id="content">
</div>
</body>
<script>
let content= document.querySelector('#content')
window.onhashchange=function(e){
console.log(window.history.state)
let {newURL}=e
if(newURL.endsWith('#/login')){
content.innerHTML='这是登录内容'
}
else if(newURL.endsWith('#/desk')){
content.innerHTML='这是桌面内容'
}
}
</script>
看下运行结果:
history模式
history模式概述
html5标准中,为 history 添加了pushState()
、replaceState()
方法,以及 onpopstate
事件。但原理和 hash 方式是相同的。
通过 history模式 实现单页路由的 URL 没有 #
。但因为没有 #
,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。
为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。
history模式底层实现原理
<body>
<a id="login" href="#">登录</a>
<a id="desk" href="#">桌面</a>
<hr>
<div id="content">
</div>
</body>
<script>
let login=document.querySelector('#login')
let content=document.querySelector('#content')
login.addEventListener('click',function(e){
e.preventDefault();
history.pushState({name:'loginname'},'login','/login')
content.innerHTML="登录"
})
let desk=document.querySelector('#desk')
desk.addEventListener('click',function(e){
e.preventDefault();
history.pushState({name:'deskname'},'desk','/desk')
content.innerHTML="桌面"
})
window.onpopstate=function(e){
let name=e.state.name
if(name=='loginname'){
content.innerHTML="这是登录"
}else{
content.innerHTML="这是桌面"
}
}
</script>
看一下运行结果,观察地址栏和hash模式的不同: