vue前端路由

实现一个 hash 路由

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
37
38
39
<!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 class="header">
<div>
<a href="#">首页</a>
</div>
<div>
<a href="#about">关于</a>
</div>
<div><a href="#me">我的</a></div>
<div onclick="window.history.go(-1)">返回</div>
</div>
</body>
<style>
.header {
background-color: black;
height: 100px;
line-height: 100px;
display: flex;
color: #fff;
justify-content: space-around;
}
a:link,
a:hover,
a:active,
a:visited {
color: #fff;
text-decoration: none;
}
</style>
<script src="./hashroutes.js"></script>
</html>

JS 部分

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
class Route {
constructor() {
console.log(this);
this.routes = {};
this.refresh = this.refresh.bind(this);
window.addEventListener("load", this.refresh);
window.addEventListener("hashchange", this.refresh);
}

route(path, callback) {
this.routes[path] = callback || function () {};
}

refresh() {
console.log(this);
let path = `/${window.location.hash.slice(1) || ""}`;
console.log(path);
let cb = this.routes[path];
cb && cb();
}
}

let Router = new Route();
let body = document.querySelector("body");
Router.route("/", function (res) {
body.style.backgroundColor = "red";
});

Router.route("/about", function () {
body.style.backgroundColor = "blue";
});

Router.route("/me", function () {
body.style.backgroundColor = "green";
});

实现一个 history 路由

hash 虽然能解决问题,但是带有#不太美观。

方法

  1. window.history.back()
  2. window.history.forward()
  3. window.history.go(number)
  4. window.history.pushState() 新增=》A B =》 A B C
  5. window.history.replaceState() 覆盖/替换 A B =》 A C
  • history 模式下可以使用 Popstate 事件来监听 url 的变化
  • pushState 和 replaceState 并不会触发 Popstate 事件
  • 哪些情况会触发 popstate 呢?
    • 浏览器的前进/后退按钮
    • history/back/forward/go

参数

  1. state:是一个对象,是一个指定网址相关的状态对象,如果不需要,可以为 null
  2. title:新页面的标题,null
  3. URL:新的网址,必须与当前页面出于同一个域,才会显示

部署 history 路由的时候,要使你的路由中的所有 path 都访问到 index.html 文件

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
<!DOCTYPE html>
<html lang="en">
<body>
<div class="header">
<div>
<a href="/gray">灰色</a>
</div>
<div>
<a href="/green">绿色</a>
</div>
<div><a href="/">白色</a></div>
<div onclick="window.history.go(-1)">返回</div>
</div>
</body>
<style>
.header {
background-color: black;
height: 100px;
line-height: 100px;
display: flex;
color: #fff;
justify-content: space-around;
}
a:link,
a:hover,
a:active,
a:visited {
color: #fff;
text-decoration: none;
}
</style>
<script src="./hashroutes.js"></script>
</html>

JS 部分

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Route {
constructor() {
this.routes = {};
this.bindPopState();
}

route(path, callback) {
this.routes[path] = callback || function () {};
}

init(path) {
window.history.replaceState({ path }, null, path);
this.execCallbackByPath(path);
}

bindPopState() {
window.addEventListener("popstate", (e) => {
const path = e.state && e.state.path;
console.log(path);
this.execCallbackByPath(path);
});
}

go(path) {
window.history.pushState(
{
path,
},
null,
path
);
this.execCallbackByPath(path);
}

execCallbackByPath(path) {
const cb = this.routes[path];
if (cb) {
cb();
}
}
}

let Router = new Route();
let body = document.querySelector("body");
Router.route("/", function (res) {
body.style.backgroundColor = "red";
});

Router.route("/about", function () {
body.style.backgroundColor = "blue";
});

Router.route("/me", function () {
body.style.backgroundColor = "green";
});

VueRouter

  1. vue router 从列表浏览了一段时间,点击进了一个详情页,然后返回的时候,我期望回到列表页还是停留在原来的浏览位置,你可以怎么做?
  • keep-alive
  • localStorage/sessionStorage + scrollTop + scrollTo
  • scrollBehavior
  1. router-view 是什么?

类似于动态的组件.

找到当前路径对应的 component, 并展示出来.


vue前端路由
https://zouhualu.github.io/20220405/vue前端路由/
作者
花鹿
发布于
2022年4月5日
许可协议