前端路由原理
# 前端路由原理
# 两种路由模式
vue-router 有两种路由模式,分别是:
- hash
- H5 history
其中,H5 history 模式需要后端的支持。
# hash 模式
# 网页 url 组成部分
首先需要知道网页 url 组成部分,以及如何通过 JS 去获取各部分。
// http://127.0.0.1:7777/vue-router.html?a=100&b=20#/aaa/bbb
location.protocol // 'http:'
location.hostname // '127.0.0.1'
location.host // '127.0.0.1:7777'
location.port // '7777'
location.pathname // '/vue-router.html'
location.search // '?a=100&b=20'
location.hash // '#/aaa/bbb'
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# hash 模式的特点
- hash 变化会触发网页跳转,即浏览器的前进、后退
- hash 变化不会刷新页面,这是 SPA 必需的特点
- hash 永远不会提交到 server 端(前端自生自灭)
# hash 模式的核心方法
# hash 模式的实现原理
通过 hash 的变化触发路由的变化,从而触发视图的渲染。
下面演示的代码核心是三部分:
- 监听 hash 变化
- 页面初次加载,获取当前 hash
- 点击按钮,通过 JS 修改 url 的 hash
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hash 模式</title>
</head>
<body>
<p>hash 模式</p>
<button id="btn-hash">修改 hash</button>
</body>
<script>
// 监听 hash 变化,有三种情况会触发:
// a. JS 修改 url
// b. 手动修改 url 的 hash(如果修改 url 的其它部分,可能会触发页面刷新)
// c. 浏览器前进、后退
window.onhashchange = (event) => {
console.log('old url', event.oldURL)
console.log('new url', event.newURL)
console.log('hash:', location.hash)
}
// 页面初次加载,获取当前 hash
document.addEventListener('DOMContentLoaded', () => {
console.log('hash:', location.hash)
})
// 点击按钮,通过 JS 修改 url 的 hash
document.getElementById('btn-hash').addEventListener('click', () => {
location.href = '#/user'
})
</script>
</html>
1
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
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
# H5 history 模式
# H5 history 模式的特点
H5 history 模式是用 url 规范的路由,但跳转时不刷新页面。
正常页面浏览:
https://github.com/xxx
刷新页面https://github.com/xxx/yyy
刷新页面https://github.com/xxx/yyy/zzz
刷新页面
改造成 H5 history 模式:
https://github.com/xxx
刷新页面https://github.com/xxx/yyy
前端跳转,不刷新页面https://github.com/xxx/yyy/zzz
前端跳转,不刷新页面
# H5 history 模式的核心方法
# H5 history 模式的实现原理
下面演示的代码核心是三部分:
- 页面初次加载,获取当前 path
- 点击按钮,通过
history.pushState
修改 url 的 hash- 第一个参数:
state
,无论何时,当通过浏览器前进、后退到达第三个参数配置的路由时,对应的该值就会携带过来 - 第二个参数:一般传递空字符串
- 第三个参数:目标路由的
path
- 第一个参数:
- 监听浏览器前进、后退
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>H5 history 模式</title>
</head>
<body>
<p>H5 history 模式</p>
<button id="btn-history">修改 url</button>
</body>
<script>
// 页面初次加载,获取 path
document.addEventListener('DOMContentLoaded', () => {
console.log('load', location.pathname)
})
// 打开一个新的路由
// 【注意】用 pushState 方式,浏览器不会刷新页面
document.getElementById('btn-history').addEventListener('click', () => {
const state = { name: 'page1' }
console.log('切换路由到', 'page1')
history.pushState(state, '', 'page1') // 重要!!
})
// 监听浏览器前进、后退
window.onpopstate = (event) => { // 重要!!
console.log('onpopstate', event.state, location.pathname)
}
</script>
</html>
1
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
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
H5 history 模式需要 server 端配合,可参考后端配置例子 (opens new window)。无论访问哪个路由,都返回 index.html
页面,再由前端通过 history.pushState
的方式触发路由的切换。
(完)