当谈到前端路由时,指的是在前端应用中管理页面导航和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属性// 映射对应的domonPopState()})})}function onPopState() {console.log(location.pathname)routes.forEach((item) => {if(item.path === location.pathname) {routeView.innerHTML = item.component}})}</script>
</body>