都快春招了,你还不来看看手撕前端的基础路由吗?

前言

什么是路由?路由最开始的概念就是服务端用来描述路径的,也就是说在前端的领域里面最开始是没有"路由"这一概念的,但是随着技术的发展,人们对网页的浏览体验要求越来越高,于是乎,前段就也有了路由怎么个玩意,当用户点击链接时不再需要刷新页面然后看着那雪白的画面发呆一秒,而是直接切换对应的展示的代码,这一特点深受广大程序猿和用户的喜爱,因此前端路由也就名正言顺火了起来,但是,你真的知道这一特点是如何实现的吗?

正文

通过Hash值修改路径

举个很简单的例子,当你打开百度官网,然后在后面接上/123456之后按下回车,这个时候虽然会显示404,但实际上你仔细观察会发现页面是进行了一次刷新的,即使刷新的再怎么快,那也是刷新了的。但如果在后面接的是#/123456呢?这个时候你就会发现,虽然页面不变,但是至少浏览器不会刷新页面了。原因也很简单,浏览器会把路径后#后面的所有东西都视作哈希值,而哈希值的改变不会引起页面的刷新。这样一来路径改了,页面也不刷新了,那如何修改页面呢?这个其实也很简,我们只需要对浏览器的地址进行监听,当地址修改后展示对应的HTML代码即可。话不多说直接上代码

首先,我们定义了一个<div>元素,它的id属性为"routerview",用于渲染不同页面的内容。

html 复制代码
<div id="routerview"></div>

接着,我们定义了一个名为routers的数组,其中包含了两个路由对象。每个路由对象都有一个path属性和一个component属性。path属性表示路由的路径,这里是以哈希符号#开头的字符串,例如"#/home""#/about"component属性表示该路径对应的组件或视图。在这个简单的示例中,我们只是使用了一个字符串来表示组件内容。

javascript 复制代码
const routers = [
  {
    path: '#/home',
    component: '这是首页'
  },
  {
    path: '#/about',
    component: '这是关于'
  }
]

然后,我们需要监听URL的变化,通常情况下能够改变URL的方式有三种分别是a标签浏览器的前进和后退以及通过修改window.location。这三种方式无一例外都会触发一个事件------hashchange,所以我们只需要使用addEventListener方法来监听浏览器的DOMContentLoaded事件(用于应对浏览器dom元素的初次加载)和hashchange事件,以便在这些事件发生时更新页面内容。当这些事件触发时,会调用onHashChange函数。

javascript 复制代码
window.addEventListener('DOMContentLoaded', onHashChange)
window.addEventListener('hashchange', onHashChange)

onHashChange函数中,我们首先使用location.hash获取当前页面的哈希值,然后遍历routers数组,根据当前哈希值来匹配对应的路由对象。如果找到了匹配的路由对象,就使用该路由对象的component属性来更新routerview元素的内容。

javascript 复制代码
function onHashChange() {
  console.log(location.hash);
  routers.forEach((item, index) => {
    if (item.path === location.hash) {
      routerview.innerHTML = item.component
    }
  })
}

这样,当用户在浏览器地址栏中输入不同的哈希值或点击页面内的链接时,页面的routerview元素会根据不同的路径显示相应的组件内容,实现了基本的前端路由功能。

总结起来,这段代码实现了基本的前端路由功能,使用了哈希路由来实现页面间的切换,并演示了如何使用location对象和addEventListener方法来监听URL的变化并动态更新页面内容。

这个方法几乎已经完美了,前提是你和你的用户不介意那个#。但这怎么可能呢,对于恨不得把前端整出花来的前端工程师来说,这个#简直就是眼中钉肉中刺,一天不去掉就一天睡不着觉,所以,接下来介绍的是另一种稍微复杂那么一点点的方法

History

既然都说了History的路径不会带有#,那么也就意味着修改URL时的值不再是哈希值,既然这样,组织页面的刷新就是就是我们最先要干的事。方法十分简单

js 复制代码
 const links = document.querySelectorAll('li a')

     links.forEach(a => {
     a.addEventListener('click', (e) => {
     e.preventDefault()
                //preventDefault函数阻止了a标签自带的跳转页面行为
                // 添加一种可以修改URL但又不刷新页面的行为
            })

这里我们是通过preventDefault方法去阻止HTML标签中自带的行为,比如常见的不让你复制内容的网页也是通过这个方法去阻止用户复制网页内容。那么到这里,页面跳转被阻止了,页面的刷新也就顺理成章没得用了。接下来的事情就和上面差不多了,也是先改变url,然后再修改对应的HTML代码

pushState

这里就不得不提到今天的主角之一了:history API,它提的了 pushState 方法,可以修改URL且不引起页面刷新。

js 复制代码
history.pushState(null, '跳转后', a.getAttribute('href'))

这个方法需要三个参数分别是state,titleURL,其中title这个参数基本不用了,但是由于种种历史原因(官方文档是这么说的)这个参数还不能被省略。这样一来,url也修改完成。剩下的就是包装一个函数用来监听url了,函数和上面差不多,这里就不过多赘述了。最后的问题来了,我们什么时候用这个函数?dom元素首次加载肯定是要的,这个不必多说,但是当我通过点击浏览器的前进或者后退呢?

popstate

这就是今天这篇文章最后的主角了,浏览器的前进或后退都会触发popstate事件,所以我们只需要添加一个时间监听popstate就可以知道用户是否在浏览器上进行了前进或者后退操作

js 复制代码
 window.addEventListener('popstate', onPopstate);

总结

利用 history API 可以方便地实现前端路由功能,从而提升单页面应用的用户体验和性能。通过定义路由表,监听 popstate 事件,以及在事件处理函数中根据 URL 的路径部分来渲染相应的视图组件,我们可以轻松地构建出一个可靠和高效的前端路由系统。然而这只是前端路由中最基础的修改页面渲染的功能,后续还有更多其他功能我也会出相关的文章介绍

相关推荐
J总裁的小芒果8 分钟前
Vue3 el-table 默认选中 传入的数组
前端·javascript·elementui·typescript
Lei_zhen9610 分钟前
记录一次electron-builder报错ENOENT: no such file or directory, rename xxxx的问题
前端·javascript·electron
咖喱鱼蛋13 分钟前
Electron一些概念理解
前端·javascript·electron
yqcoder14 分钟前
Vue3 + Vite + Electron + TS 项目构建
前端·javascript·vue.js
鑫宝Code31 分钟前
【React】React Router:深入理解前端路由的工作原理
前端·react.js·前端框架
Mr_Xuhhh2 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
永乐春秋3 小时前
WEB攻防-通用漏洞&文件上传&js验证&mime&user.ini&语言特性
前端
鸽鸽程序猿3 小时前
【前端】CSS
前端·css
ggdpzhk3 小时前
VUE:基于MVVN的前端js框架
前端·javascript·vue.js
学不会•5 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html