当谈到前端路由时,指的是在前端应用中管理页面导航和URL的机制。前端路由使得单页应用(Single-Page Application,SPA)能够在用户与应用交互时动态地加载不同的视图,而无需每次都重新加载整个页面。
在前端开发中,常用的前端路由库有很多,比如React Router、Vue Router和Angular Router等。这些库提供了一组API和组件,用于定义路由规则、处理导航事件和渲染相应的视图。
简单了解前端路由后,那么前端路由实现的原理是什么呢?
浏览器的url变了需要映射到页面的某个组件,url变了需要展示某个组件。/home和Home.vue,/about和About.vue就是一一映射的关系。这个时候你就想起来router中index.js文件中,一个path对应一个component,也就是一个路径对应一个组件
1、实现路由需要解决的问题
- 1.如何修改url还不引起页面的刷新
- 2.如何知道url变化了
若是能解决这两个问题就可以实现前端路由了。
2、哈希Hash 路由
哈希是一种值,按照某种规则生成的一串值,用来代表一个唯一的文件,文件名后加一个哈希值,可以看到文件是否被修改过。
在浏览器中也有hash这个概念,url中接一个#,#后的值就是哈希值,按道理url变了,页面一定会刷新,但是哈希是个特例,放个哈希值就是不会刷新页面,这样,我们就解决了第一个问题,修改url不引起页面的刷新
- 核心api hashchange
效果:
哈希路由实现原理,上代码
<body>
<!-- 模拟单页页面应用 -->
<ul>
<li><a href="#/home">首页</a></li>
<li><a href="#/about">关于</a></li>
<!-- 判断url的变化,绑定点击事件不好,页面过多就很累赘,有个hashchange的官方方法 -->
</ul>
<div id="routeView">
<!-- 放一个代码片段 点击首页首页代码片段生效,反之关于生效-->
</div>
<script>
const routes = [
{
path: '#/home',
component: '首 容'
},
{
path: '#/about',
component: '关于页面内容'
}
]
const routeView = document.getElementById('routeView')
window.addEventListener('DOMContentLoaded', onHashChange) // 与vue的声明周期一个道理,dom一加载完毕就触发
window.addEventListener('hashchange', onHashChange)
function onHashChange() {
console.log(location) // url详情,里面就有个hash值 liveserver可以帮你把html跑成服务器
routes.forEach((item, index) => {
if(item.path === location.hash) {
routeView.innerHTML = item.component
}
})
}
</script>
</body>
3、history 路由
- 核心api popstate pushState
效果:
history 路由 实现原理,上代码
<body>
<ul>
<li><a href="/home">首页</a></li>
<li><a href="/about">关于</a></li>
</ul>
<div id="routeView">
</div>
<script>
const routes = [
{
path: '/home',
component: '首页内容'
},
{
path: '/about',
component: '<h1>关于页面内容</h1>'
}
]
const routeView = document.getElementById('routeView')
window.addEventListener('DOMContentLoaded', onLoad)
window.addEventListener('popstate', onPopState)
function onLoad() {
const links = document.querySelectorAll('li a') // 获取所有的li下的a标签
// console.log(links)
links.forEach((a) => {
// 禁用a标签的默认跳转行为
a.addEventListener('click', (e) => {
console.log(e)
e.preventDefault() // 阻止a的跳转行为
history.pushState(null, '', a.getAttribute('href')) // 核心方法 a.getAttribute('href')获取a标签下的href属性
// 映射对应的dom
onPopState()
})
})
}
function onPopState() {
console.log(location.pathname)
routes.forEach((item) => {
if(item.path === location.pathname) {
routeView.innerHTML = item.component
}
})
}
</script>
</body>