首页 > 其他分享 >#yyds干货盘点#讲讲前端路由的原理

#yyds干货盘点#讲讲前端路由的原理

时间:2022-10-06 18:32:15浏览次数:51  
标签:yyds hash url routerView 干货 跳转 路由 页面

什么是前端路由

前端的路由可以理解成:用来描述 url(web页面的地址) 与 UI(用户界面) 之间的映射关系,就是当 url 发生变化,那么 UI 也会发生变化,那么这种映射关系就叫前端的路由。并且这个路由是一种单向映射的,url==>UI

为什么要有前端路由

随着单页Web应用(说通俗点就是在页面里面如果要查看某条数据的具体内容,但是鼠标点击进去浏览器不会产生一个新的页面)的广大应用,在单页面应用里如何进行数据的变化以及页面的跳转从而使得单页面应用即使只有一个html文件,但是也可以像多页面应用一样包含丰富的内容;此时前端路由就应运而生。

如何实现前端路由

如何实现前端的路由,问题有哪些?

我们都知道在页面上,当页面的url地址改变了,那么这个页面的UI也就会相应的发生改变;我们点击页面上的某个地方,就可能会导致url地址的改变,从而导致UI的改变。

那么第一个问题就来了:当url发生改变的时候,如何检测到url发生变化 ?

解决了第一个问题接下来的问题就是:监测到url发生变化,我们就要渲染相应改变后url的页面,在改变url的同时但是不引起页面刷新,让这个页面至始至终都是一个单页面应用。


方法一:hash

首先我们要知道浏览器也有hash,就是某个页面url地址#后面跟着的东西,例如:

https://blog.51cto.com/blogger/publish?old=1#heading1

并且改变url中的hash值部分,页面是不会刷新的,所以这里就解决了第二个问题,那么如何检测到url发生变化? 我们又要知道浏览器有可以检测到hash值改变的方法:hashchange方法

我们只要检测到hash值的改变,获取到当前改变后的hash值,再根据hash值来切换页面内容就可以了。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<!-- 加了# 浏览器会将其认成一个hash值,从而不刷新页面 -->
<li> <a href="#/home">首页</a></li>
<li><a href="#/about">关于</a></li>
</ul>

<!-- 渲染对应的UI -->
<div id="routerView"></div>
<script>
let routerView = document.getElementById('routerView')
window.addEventListener('hashchange', onHashChange ) // 浏览器可以检测到hash值改变,监听hash值的改变;如果改变就触发onHashChange函数

// 检测hash值的改变,控制渲染对应的UI
function onHashChange(){
console.log(location.hash); // 本地的hash值
switch(location.hash){
case '#/home':
routerView.innerHTML='Home'
return
case '#/about':
routerView.innerHTML='About'
return
default:
return
}
}
routerView.innerHTML='Home'
</script>
</body>
</html>

方法二:history 模式

history是HTML5提供的一个对象方法,并且它提供三个方法:

  1. pushState
  2. replaceState // 1与2这两个方法都是修改url的,并且这两个方法修改url的时候,是不会引起页面刷新的
  3. popState // 监听url的变化

这三个方法简直就是为前端路由而生呀!

这个方法原理就是:当我们在页面点击某处要切换内容,如果我们不使用hash值就必然会导致页面的刷新,那么我们要做的就是将这个页面跳转遏制住,此时我们就要知道有个阻止默认事件发生的函数:preventDefault();让这个函数阻止页面跳转这个默认行为。然后我们再使用pushState或者replaceState方法与popState方法配合,当我们点击跳转页面时,首先拦截下来跳转这个行为,然后使用pushState或者replaceState方法进行不刷新页面跳转,再监听页面跳转这一行为,然后匹配对应页面的内容,这样前端路由就实现了呀。 代码实现:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li><a href="/home">首页</a></li>
<li><a href="/about">关于</a></li>
</ul>

<!-- 渲染对应的UI -->
<div id="routerView"></div>

<script>
let routerView = document.getElementById('routerView') // 控制它显示DOM结构

window.addEventListener('DOMContentLoaded', onl oad) // 一开始加载页面的时候,监听页面加载,调用onLoad函数
window.addEventListener('popstate', onPopState) // 浏览器的前进后退能匹配

function onl oad() {
onPopState() // 匹配路径,展示对应的html

let links = document.querySelectorAll('li a[href]') // 获取a标签的href属性
// 拦截a标签的默认跳转行为
links.forEach(a => {
a.addEventListener('click', (e) => { // 当我们点击a标签时,阻止跳转页面的行为
e.preventDefault() // 阻止a标签的href行为

history.pushState(null, '', a.getAttribute('href')) // 跳转,第三个参数就是要跳转的页面
onPopState() // 再匹配路径,展示对应的html
})
})
}
// 匹配路径,展示对应的html
function onPopState() {
// console.log(location.pathname);
switch (location.pathname) {
case '/home':
routerView.innerHTML = '<h2>home page</h2>'
return
case '/about':
routerView.innerHTML = '<h2>about page</h2>'
return
default:
return
}
}
</script>
</body>
</html>

标签:yyds,hash,url,routerView,干货,跳转,路由,页面
From: https://blog.51cto.com/u_11365839/5733951

相关文章

  • 干货——线性分类(上)
    线性分类图像分类的任务,就是从已有的固定分类标签集合中选择一个并分配给一张图像。我们还介绍了k-NearestNeighbor(k-NN)分类器,该分类器的基本思想是通过将测试图像与训练......
  • 干货 | 快速端到端嵌入学习用于视频中的目标分割
    公众号ID|ComputerVisionGzq学习群|扫码在主页获取加入方式暗中观察默默关注那我们开始进入今天的主题,接下来主要和大家分享目标在视频中的实时分割技术,来,一起学习吧!背景及动......
  • vue路由懒加载(延迟加载)的写法..
    路由懒加载可以帮我们在进入首屏时不用加载过度的资源,从而减少首屏加载速度。(1)路由文件中,非懒加载写法:importIndexfrom'@/page/index/index';exportdefaultnew......
  • 路由(选择)协议
    基本概念理想的路由算法算法必须是正确的和完整的。算法在计算上应简单。算法应能适应通信量和网络拓扑的变化,这就是说,要有自适应性。算法应具有稳定性。算法应是公......
  • 干货 | 实战演练基于加密接口测试测试用例设计
    如果接口测试仅仅只是掌握一些requests或者其他一些功能强大的库的用法,是远远不够的,还需要具有根据公司的业务以及需求去定制化一个接口自动化测试框架能力。所以在这个部分......
  • 干货 | 通用 api 封装实战,带你深入理解 PO
    在普通的接口自动化测试中,如果接口的参数,比如url,headers等传参改变,或者测试用例的逻辑、断言改变,那么整个测试代码都需要改变。apiobject设计模式借鉴了pageobject的设计模......
  • VMware Workstation安装软路由OpenWrt
    OpenWrt可以被描述为一个嵌入式的Linux发行版。(主流路由器固件有dd-wrt,tomato,openwrt,padavan四类)对比一个单一的、静态的系统,OpenWrt的包管理提供了一个完全可写的文......
  • 云架构系统如何做性能分析?| 实战干货
    性能分析一直是性能实施项目中的一个难点。对于只做性能测试不做性能分析的团队来说,总是不能把问题非常显性地展示出来,不能给其他团队非常明确的引导。对于这种类型的测试实......
  • #yyds干货盘点# 软件测试的目的和对象
    一、不论是哪个时期的定义,软件测试的目的实际上是一致的,这个目的就是“保证软件质量”。具体来讲就是要保证软件或系统符合相关的法律法规、技术标准和应用需求,降低软件的......
  • #yyds干货盘点#【愚公系列】2022年10月 Go教学课程 038-异常处理
    一、异常处理1.什么是异常处理异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况,异常处理的好处是你不用再绞尽脑汁去考虑各种错误,这为......