路由
# 路由
# 路由简介
- 路由就是通过互联的网络把信息从源地址传送到目的地的活动,网络工程术语
- 路由提供了两种机制:路由和传送
- 路由是决定数据包从来源到目的地的路径
- 转送就是将数据转移
- 路由表
- 路由表本质就是一个映射表,决定了数据包的指向
# 历史 🔥
后端渲染,服务端渲染(后端路由)阶段:前端请求一个 URL 后,由例如 Java 如 SpringMVC 中 @RequestMapping 来映射到 Java 代码中,并通过 Servlet 和 JSP 技术编写 HTML 页面(JS+CSS)并填充数据,最后返回给前端完整的 HTML,前端直接渲染展示即可。这种由后端处理 URL 和页面映射关系的称为后端路由。
前后端分离阶段(Gmail 的 Ajax 大量使用) :前端请求一个 URL 后,可能先从静态资源服务器获取一套 HTML+CSS+JS(服务器中有多套),之后再由 JS 发送 Ajax 请求到后端,由后端返回如 JSON 数据交给前端,前端使用 JS 进行数据填充,渲染 DOM。每次 URL 改变都会请求后端服务器拿静态资源和数据。
单页面富应用(SPA 页面),前后端分离加上前端路由阶段: 前端第一次请求 URL 后,会从如静态资源服务器获取一套完整的 HTML+CSS+JS(只有一个 HTML,其他 JS 或 CSS 可能会懒加载),之后的 URL 改变不会向后端服务器发送请求,页面不进行整体刷新,而是由其不同的 URL 页面自己发送 Ajax 请求获取数据并由 JS 进行数据填充,渲染 DOM。这种由前端处理 URL 和页面的映射关系称为前端路由。
那么如何在 URL 改变后页面还不进行整体刷新呢?且看下面介绍。
# URL 的 hash & HTML5 的 history 🔥
提示
Vue CLI 初始化项目时推荐选择 history 模式。URL 看起来更友好,没有#这玩意
# hash—URL
URL 的 hash 是改变锚点#,其本质上改变的是 window.location.hash 属性,不是 href 属性
location.hash = '/user/10000'
http://localhost:8082/#/user/10000
location.hash = '/role/1'
http://localhost:8082/#/role/1
2
3
4
5
原理
<!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>
<div id="app">
<a href="#/home">home</a>
<a href="#/about">about</a>
<div class="content">Default</div>
</div>
<script>
const contentEl = document.querySelector('.content');
window.addEventListener("hashchange", () => {
switch(location.hash) {
case "#/home":
contentEl.innerHTML = "Home";
break;
case "#/about":
contentEl.innerHTML = "About";
break;
default:
contentEl.innerHTML = "Default";
}
})
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# history—HTML5
HTML5 的 history。是一个栈结构
history.pushState('','','/user/100001')
http://localhost:8082/user/100001
history.pushState('','','/role/1')
http://localhost:8082/role/1
history.back()
http://localhost:8082/user/100001
history.forward()
http://localhost:8082/role/1
history.replaceState('','','/permission/100')
http://localhost:8082/permission/100
# 此时将上面的 http://localhost:8082/role/1 替换掉了,之后无法 back 回去,只能 back 到 http://localhost:8082/user/100001
# go 可以更灵活控制,相比 back,forward
history.go(-1)
history.go(1)
history.go(-2)
history.go(2)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Vue Router 就是将组件和 URL 映射
原理
<!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>
<div id="app">
<a href="/home">home</a>
<a href="/about">about</a>
<div class="content">Default</div>
</div>
<script>
const contentEl = document.querySelector('.content')
const changeContent = () => {
console.log('-----')
switch (location.pathname) {
case '/home':
contentEl.innerHTML = 'Home'
break
case '/about':
contentEl.innerHTML = 'About'
break
default:
contentEl.innerHTML = 'Default'
}
}
const aEls = document.getElementsByTagName('a')
for (let aEl of aEls) {
aEl.addEventListener('click', (e) => {
// 取消a标签的默认行为
e.preventDefault()
const href = aEl.getAttribute('href')
// 压栈操作,可back
// history.pushState({}, "", href);
// 替换操作,无法back
history.replaceState({}, '', href)
changeContent()
})
}
window.addEventListener('popstate', changeContent)
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53