前端路由的概念
路由的概念是服务器上,URL和处理函数的映射关系
- 前段路由在单页应用中体现,描述的是URL和UI页面的映射关系,即URL变了 —— UI更新(无需刷新页面)
如何实现前端路由
这里有俩个问题:
- 如何改变URL却不影响页面的刷新?
- 如何检测到URL变化了?
解决方法:
1. hash实现
- hash是URL中 # 后面的那一部分,改变URL中的hash,页面不刷新,在#后面拼接url地址,这就解决了问题一。
- hashchange 用于监听页面的hash值发生变化,只要页面的url发生变化这个函数就会触发。这是原生js提供的方法。第二个问题就得到了解决。
接下来我们看一个例子的核心代码:
要求:在页面上定义两个a标签,点击标签跳转时显示对应的页面内容,并且页面不发生刷新。
<body>
<ul>
<li><a href="#/home">home</a></li>
<li><a href="#/about">about</a></li>
</ul>
<div id="routerView"></div>
<script>
//拿到dom结构
var routerView = document.getElementById('routerView')
//监听dom结构加载完毕后,就先调用一次
window.addEventListener('DOMContentLoaded',onHashChange)
//hashchange 监听URL发生变化
window.addEventListener('hashchange',onHashChange)
function onHashChange(){
//获取当前浏览器的URL
console.log(location.hash);
switch(location.hash){ //匹配对应url的页面内容
case '#/home':routerView.innerHTML = 'Home page'
return
case '#/about' : routerView.innerHTML = 'About page'
return
default:
return
}
}
</script>
</body>
实现效果:
我们可以看到当该改变url后显示出了对象的页面内容,并且页面没有发生刷新。
2. hsitory
- history是HTML提供的一个对象,其中提供了pushState 和 replaceShashchangetate 俩个方法,这俩个方法都可以改变URL且不引起页面刷新。也提供了一个popstate方法,作用和hashchange类似。
- pushState 和 replaceState的调用 和 a标签的点击事件是可以被拦截的。其原理就是拦截下来a标签的点击事件,并让其href属性不生效,达到页面不刷新的效果。
跟上面同样的例子:
<body>
<ul>
<li><a class="link1" href="/home">home</a></li>
<li><a class="link2" href="/about">about</a></li>
</ul>
<div id="routerView"></div>
<script>
//只要是用pushState 或 replaceState 让url变化的 就会被监听到
window.addEventListener('popstate',onPopState)
//拿到当前页面路径并匹配对应页面
function onPopState(){
switch(location.pathname){
case '/home':
routerView.innerHTML = '<h2>Home</h2>'
return
case '/about':
routerView.innerHTML = '<h2>About</h2>'
return
default:
return
}
}
//页面dom结构加载完成之后,调用onload
window.addEventListener('DOMContentLoaded',onLoad)
function onLoad(){
var routerView = document.getElementById('routerView')
//拦截a标签的点击事件
var linkList = document.querySelectorAll('ul li a')
linkList.forEach(el =>{
el.addEventListener('click',function(e){
//阻止默认事件
e.preventDefault();
//用pushState 或 replaceState手动修改URL
history.pushState(null,'',el.getAttribute('href'))
})
})
}
</script>
</body>
这个过程就是拿到a标签,禁用掉其默认跳转事件,然后通过 pushState 或 replaceState手动修改要跳转的地址,popstate就会监听到,最后对应url渲染页面内容。
实现效果: