# 5. 路由-vue-router
https://router.vuejs.org/zh/api/
# 路由基本使用
<!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>Document</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入Vue路由依赖js -->
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<!-- 路由跳转需要带上 # 号,因为 Vue-router 是基于哈希进行路由匹配的 -->
<a href="#/login">login</a>
<a href="#/register">register</a>
<!-- 这是 vue-router 提供的元素,专门用来当做占位符。 -->
<!-- 将来路由规则匹配到的组件就会展示到这个router-view中 -->
<router-view></router-view>
</div>
</body>
<script>
// 组件的模板对象
var login = {
template: '<h1>登录组件</h1>'
}
var register = {
template: '<h1>注册组件</h1>'
}
// 创建一个路由对象,当导入包后,在window全局对象中,就有了一个路由的构造函数,叫做VueRouter
// 在new路由对象的时候,可以为构造函数,传递一个配置对象
var router = new VueRouter({
// 这个配置对象中的 route 表示【路由匹配规则】的意思。
routes: [
// 路由匹配规则
// 每个路由规则,都是一个对象,这个规则对象身上有两个必须的属性:
// 属性 1 是 path ,表示监听哪个路由链接地址;
// 属性 2 是 component,表示如果路由是前面匹配到的 path ,则展示 component 属性对应的那个组件。
// 注意:component 的属性值,必须是组件的对象,不能是组件名称。
{ path: '/login', component: login },
{ path: '/register', component: register }
]
})
//
var vm = new Vue({
el: '#app',
data: {},
methods: {},
router // 将路由规则对象,注册到Vue实例上,用来监听Url地址的变化,然后展示对应的组件。
})
</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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
56
57
58
59
60
61
62
63
# 路由跳转标签
router-link
Vue-router 官方提供了一个router-link
元素标签。
它可以实现<a>
标签的路由跳转,并且最终会渲染成为一个<a>
标签,从而不需要在<a>
标签中的href
地址加#
号进行跳转。
该元素有一个元素to
属性,相当于<a>
标签的href
属性。
<router-link to='/login'>登录</router-link>
1
# 重定向方式
redirect
有一个需求,需要将项目根目录默认跳转到登录组件,可使用redirect
重定向去登录的路由。
var router = new VueRouter({
routes: [
// 使用 redirect 重定向到登录路由。
{ path: '/', redirect: '/login' },
{ path: '/login', component: login },
{ path: '/register', component: register }
]
})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 修改router-link
激活class
默认值
配置当链接被精确匹配的时候应该激活的 class
。注意默认值也是可以通过路由构造函数选项 linkExactActiveClass
进行全局配置的。
var router = new VueRouter({
routes:[
// 路由匹配...
],
// 修改默认的激活 class 为 myActive
linkExactActiveClass: 'myActive'
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 在路由中定义动画
<!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>Document</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入Vue路由依赖js -->
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>
<style>
.myActive {
color: brown;
}
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(140px);
}
.v-enter-active,
.v-leave-active {
transition: all 0.5s ease;
}
</style>
</head>
<body>
<div id="app">
<router-link tag='span' to='/login'>登录</router-link>
<router-link tag='span' to='/register'>注册</router-link>
<!-- 直接使用 transition 包裹起来 -->
<transition mode='out-in'>
<router-view></router-view>
</transition>
</div>
</body>
<script>
var login = {
template: '<h1>登录组件</h1>'
}
var register = {
template: '<h1>注册组件</h1>'
}
var router = new VueRouter({
routes: [
{ path: '/login', component: login },
{ path: '/register', component: register }
],
linkExactActiveClass: 'myActive'
})
var vm = new Vue({
el: '#app',
data: {},
methods: {}
})
</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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
56
57
58
59
60
61
62
63
64
65
66
67
# 在路由规则中定义参数
# 第一种方式
- 在
router-link
标签的to
属性中添加?xx=xx
的形式把参数绑定在地址上。 - 通过
this.$route.query
来获取绑定在地址上的参数。
<router-link to='/login?id=12'>登录</router-link>
<script>
var login = {
template: '#login',
created() {
console.info(this.$route.query.id)
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 第二种方式
- 在规则中定义参数
{ path:'/login:id',component: login }
var router = new VueRouter({
routes: [
{ path: '/login/:id/:name', component: login }
]
})
1
2
3
4
5
2
3
4
5
- 在
router-link
标签的to
属性中添加对应的参数
<router-link to='/login/12/张三'>登录</router-link>
1
- 通过
this.$route.params
来获取路由中的参数:
var login = Vue.extend({
template: '<h1>登录组件 --- {{ this.$route.params.id }}</h1>'
})
1
2
3
2
3
# 使用children
属性实现路由嵌套
路由嵌套简单来说就是父子路由,关键属性children
。
示例
<!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>Document</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入Vue路由依赖js -->
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>
<style>
.myActive {
color: brown;
}
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(140px);
}
.v-enter-active,
.v-leave-active {
transition: all 0.5s ease;
}
</style>
</head>
<body>
<div id="app">
<router-link to='/account'>Account</router-link>
<transition mode='out-in'>
<router-view></router-view>
</transition>
</div>
<template id='account'>
<div>
<h3>账号组件</h3>
<!-- 如果在路由中,允许使用?xx=xx传参 -->
<router-link to='/account/login'>登录</router-link>
<router-link to='/account/register'>注册</router-link>
<transition mode='out-in'>
<router-view></router-view>
</transition>
</div>
</template>
<template id='login'>
<div>
<h3>登录组件</h3>
</div>
</template>
<template id='register'>
<div>
<h3>注册组件</h3>
</div>
</template>
</body>
<script>
var login = {
template: '#login'
}
var register = {
template: '#register'
}
var account = {
template: '#account',
}
var router = new VueRouter({
routes: [
{
path: '/account',
component: account,
// 使用 children 实现子路由的切换,注意 path 不要加`/`,否则永远以根路径匹配。
// 下列所示 最终请求以 /account/login 访问。
children: [
{ path: 'login', component: login },
{ path: 'register', component: register }
]
}
],
linkExactActiveClass: 'myActive'
})
var vm = new Vue({
el: '#app',
data: {},
methods: {},
router
})
</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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# 命名视图实现经典布局
在日常开发中,我们常见的项目采用的是经典的布局,有头部,左侧菜单,还有中间的主要内容。
使用VueRouter可以实现对组件命名,在router-view
中指定name
属性来进行组件的指定显示,从而实现一个页面多个组件显示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入Vue路由依赖js -->
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>
<style>
html,
body {
margin: 0;
padding: 0;
}
.header {
background-color: orange;
height: 80px;
}
.container {
display: flex;
height: 600px;
}
h1 {
margin: 0;
padding: 0;
font-size: 16px;
}
.left {
background-color: lightgreen;
flex: 2;
}
.main {
background-color: pink;
flex: 10;
}
</style>
</head>
<body>
<div id="app">
<router-view></router-view>
<!-- 命名视图 -->
<div class="container">
<router-view name='left'></router-view>
<router-view name='main'></router-view>
</div>
</div>
</body>
<script>
var header = {
template: '<h1 class="header">头部区域</h1>'
}
var menuBox = {
template: '<h1 class="left">左部菜单区域</h1>'
}
var mainBox = {
template: '<h1 class="main">主内容区域</h1>'
}
var router = new VueRouter({
routes: [
{
path: '/', components: {
// default 相当于默认,即标签上没有name属性时默认显示该组件
'default': header,
'left': menuBox,
'main': mainBox
}
}
]
})
var vm = new Vue({
el: '#app',
data: {},
methods: {},
router
})
</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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89