路由的基本概念

image-20201102135258470

image-20201102135508671

VueRouter基本使用

官方地址:https://router.vuejs.org/zh/

  1. 引入相关库文件

    VueRouter依赖于vue,因此需要先引入vue

    1
    2
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router_3.0.2.js"></script>
  2. 添加路由链接

    1
    2
    <router-link to='/user'>user</router-link>
    <router-link to='/register'>register</router-link>

    router-link标签会被渲染成a标签,to属性则会被渲染成href属性。

  3. 添加路由填充位

    1
    <router-view></router-view>
  4. 定义路由组件

    1
    2
    3
    4
    5
    6
    const User = {
    template: '<div>User组件</div>'
    }
    const Register = {
    template: '<div>Register组件</div>'
    }
  5. 配置路由规则并创建路由实例

    1
    2
    3
    4
    5
    6
    7
    8
    // 创建路由实例对象
    const router = new VueRouter({
    // 所有路由规则
    routes: [
    { path: '/user', component: User },
    { path: '/register', component: Register },
    ]
    })
  6. 把路由挂载到Vue根实例中

    1
    2
    3
    4
    let app = new Vue({
    el: '#app',
    router: router
    })

完整版的案例:

87110fcb-76ee-48b3-9546-badfde499d9d

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>

<body>
<div id="app">

<router-link to='/user'>user</router-link>
<router-link to='/register'>register</router-link>

<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.4.8/dist/vue-router.js"></script>
<script>
const User = {
template: '<div>User组件</div>'
}
const Register = {
template: '<div>Register组件</div>'
}
// 创建路由实例对象
const router = new VueRouter({
// 所有路由规则
routes: [
{ path: '/user', component: User },
{ path: '/register', component: Register },
]
})

let app = new Vue({
el: '#app',
router: router
})
</script>
</body>

</html>

重定向

路由规则存在redirect属性,可以实现重定向。

1
2
3
4
5
6
7
8
const router = new VueRouter({
// 所有路由规则
routes: [
{ path: '/', redirect: '/user' },
{ path: '/user', component: User },
{ path: '/register', component: Register },
]
})

嵌套路由

  1. 创建父级路由链接和父级路由填充位

  2. 子路由链接和子路由填充位

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const Register = {
    template: `
    <div>
    <h1>Register组件</h1>
    <!-- 子路由链接 -->
    <router-link to='/register/tab1'>tab1</router-link>
    <router-link to='/register/tab2'>tab2</router-link>

    <!-- 子路由占位符 -->
    <router-view></router-view>
    </div>
    `
    }

    子路由的链接及占位符需要定义在父路由的模板中。

  3. 父级路由通过children属性配置子集路由

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    const Tab1 = {
    template: '<h3>Tab1子组件</h3>'
    }
    const Tab2 = {
    template: '<h3>Tab2子组件</h3>'
    }
    // 创建路由实例对象
    const router = new VueRouter({
    // 所有路由规则
    routes: [
    { path: '/', redirect: '/user' },
    { path: '/user', component: User },

    {
    path: '/register', component: Register, children: [
    { path: '/register/tab1', component: Tab1 },
    { path: '/register/tab2', component: Tab2 },
    ]
    },
    ]
    })

    children属性表示子路由,是一个数组,使用方式与routers属性类似。

image-20201102143540342

路由传递参数

基本用法

动态路由规则使用:开头。在组件中通过$route.params获取。

1
2
3
<router-link to='/user/1'>user</router-link>
<router-link to='/user/2'>user</router-link>
<router-link to='/user/3'>user</router-link>
1
2
3
4
5
6
7
8
const User = {
template: '<div>User{{$route.params.id}}组件</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User },
]
})

组件传参

props为布尔值

  1. 开启props传参

    1
    2
    3
    4
    5
    6
    const router = new VueRouter({
    // 所有路由规则
    routes: [
    { path: '/user/:id', component: User, props: true },
    ]
    })

    props的值是一个布尔类型的值。

  2. 接受属性

    1
    2
    3
    4
    const User = {
    props: ['id'],
    template: '<div>User{{id}}组件</div>'
    }

props为对象

传递对象时会导致无法匹配路由时所传递的参数。

  1. 开启props传参

    1
    2
    3
    4
    5
    6
    const router = new VueRouter({
    // 所有路由规则
    routes: [
    { path: '/user/:id', component: User, props: { name: '张三' } },
    ]
    })
  2. 接受属性

    1
    2
    3
    4
    const User = {
    props: ['name'],
    template: '<div>User{{name}}组件</div>'
    }

函数类型

函数类型可以获取路由中传递的值,也可以返回自定义的值。

传递对象时会导致无法匹配路由时所传递的参数。

  1. 开启props传参

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const router = new VueRouter({
    // 所有路由规则
    routes: [
    {
    path: '/user/:id', component: User, props: router => ({
    name: '张三',
    id: router.params.id
    })
    },
    ]
    })
  2. 接受属性

    1
    2
    3
    4
    const User = {
    props: ['id', 'name'],
    template: '<div>User{{name}}组件{{id}}</div>'
    }

9341765a-51ae-48bc-8159-3b2427a3d778

命名路由

即对路由起一个别名,当使用router-link的to属性时绑定一个对象,通过name属性表示跳转的路由,params表示携带的参数。

1
2
3
4
5
6
7
8
9
10
11
12
const router = new VueRouter({
// 所有路由规则
routes: [
{
name: 'user',
path: '/user/:id', component: User, props: router => ({
name: '张三',
id: router.params.id
})
},
]
})
1
<router-link :to='{name:"user",params:{id:"3"}}'>user</router-link>

image-20201102145723058

编程式导航

  1. 通过this.$router.push指定跳转的路由

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const User = {
    props: ['id', 'name'],
    template: `
    <div>User{{name}}组件{{id}}
    <button @click='goPush'>跳转</button>
    </div>
    `,
    methods: {
    goPush: function () {
    this.$router.push('/register')
    }
    },
    }

    push可以传递参数的类型:

    1
    2
    3
    4
    5
    6
    7
    8
    // 字符串(路径名称)
    this.$router.push('/register')
    // 对象
    this.$router.push({ path: '/register' })
    // 命名的路由(传递参数)
    this.$router.push({ name: '/user', params: { userId: 123 } })
    // 带查询参数,变成/register?uname=lisi
    this.router.push({ path: '/register', query: { uname: 'lissi' } })
  2. 通过this.$router.go指定回退或前进的步数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const Register = {
    template: `
    <div>Register组件
    <button @click='go'>跳转</button>
    </div>
    `,
    methods: {
    go: function () {
    // 正数表示前进的步数,负数表示后退的步数
    this.$router.go(-1)
    }
    },
    }

携带参数

  1. 如果使用name那么使用params

    1
    2
    3
    4
    this.$router.push({
    name: '/goods/edit',
    params: { a: 1 }
    })
  2. 如果使用path那么使用query

    1
    2
    3
    4
    this.$router.push({
    path: '/goods/edit',
    query: { a: 1 }
    })

案例:后台管理路由

地址:Demo

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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>基于vue-router的案例</title>
<style type="text/css">
html,
body,
#app {
margin: 0;
padding: 0px;
height: 100%;
}

.header {
height: 50px;
background-color: #545c64;
line-height: 50px;
text-align: center;
font-size: 24px;
color: #fff;
}

.footer {
height: 40px;
line-height: 40px;
background-color: #888;
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
}

.main {
display: flex;
position: absolute;
top: 50px;
bottom: 40px;
width: 100%;
}

.content {
flex: 1;
text-align: center;
height: 100%;
}

.left {
flex: 0 0 20%;
background-color: #545c64;
}

.left a {
color: white;
text-decoration: none;
}

.right {
margin: 5px;
}

.btns {
width: 100%;
height: 35px;
line-height: 35px;
background-color: #f5f5f5;
text-align: left;
padding-left: 10px;
box-sizing: border-box;
}

button {
height: 30px;
background-color: #ecf5ff;
border: 1px solid lightskyblue;
font-size: 12px;
padding: 0 20px;
}

.main-content {
margin-top: 10px;
}

ul {
margin: 0;
padding: 0;
list-style: none;
}

ul li {
height: 45px;
line-height: 45px;
background-color: #a0a0a0;
color: #fff;
cursor: pointer;
border-bottom: 1px solid #fff;
}

table {
width: 100%;
border-collapse: collapse;
}

td,
th {
border: 1px solid #eee;
line-height: 35px;
font-size: 12px;
}

th {
background-color: #ddd;
}
</style>
<script src="../js/vue.js"></script>
<script src="../js/vue-router_3.0.2.js"></script>
</head>

<body>
<div id="app">
<router-view></router-view>
</div>

<script>
const app = {
template: `
<div>
<!-- 头部区域 -->
<header class="header">传智后台管理系统</header>
<!-- 中间主体区域 -->
<div class="main">
<!-- 左侧菜单栏 -->
<div class="content left">
<ul>
<li><router-link to='/users'>用户管理</router-link></li>
<li><router-link to='/rights'>权限管理</router-link></li>
<li><router-link to='/goods'>商品管理</router-link></li>
<li><router-link to='/orders'>订单管理</router-link></li>
<li><router-link to='/settings'>系统设置</router-link></li>
</ul>
</div>
<!-- 右侧内容区域 -->
<div class="content right">
<router-view />
</div>
</div>
<!-- 尾部区域 -->
<footer class="footer">版权信息</footer>
</div>
`}

const Users = {
data: function () {
return {
userList: [
{ id: 1, name: '张三', age: 10 },
{ id: 2, name: '李四', age: 11 },
{ id: 3, name: '王五', age: 12 },
{ id: 4, name: '赵六', age: 13 },
]
}
},
methods: {
goDetail: function (id) {
this.$router.push('/userinfo/' + id)
}
},
template: `
<div>
<h3>用户管理区域</h3>
<table>
<thead>
<tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
</thead>
<tbody>
<tr v-for='item in userList' :key='item.id'>
<th>{{item.id}}</th>
<th>{{item.name}}</th>
<th>{{item.age}}</th>
<th><a @click='goDetail(item.id)' href='javascript:;'>操作</a></th>
</tr>
</tbody>
</table></div>
`
}
const UserInfo = {
props: ['id'],
template: `<div>
<h5>用户详情页-{{id}}</h5>
<button @click="goback()">回退</button>
</div>`,
methods: {
goback: function () {
this.$router.go(-1)
}
},
}
const Rights = {
template: `
<h3>权限管理区域</h3>
`
}
const Goods = {
template: `
<h3>商品管理区域</h3>
`
}
const Orders = {
template: `
<h3>订单管理区域</h3>
`
}
const Settings = {
template: `
<h3>系统设置区域</h3>
`
}
// 创建路由对象
const router = new VueRouter({
routes: [
{
path: '/',
component: app,
redirect: '/users',
children: [
{ path: '/users', component: Users },
{ path: '/userinfo/:id', component: UserInfo, props: true },
{ path: '/rights', component: Rights },
{ path: '/goods', component: Goods },
{ path: '/orders', component: Orders },
{ path: '/settings', component: Settings },
]
},
]
})
let vm = new Vue({
el: '#app',
router
})
</script>
</body>

</html>