【Vue】Vue基础教程(6)
前言:
本文内容:嵌套路由、参数传递及重定向、404和路由钩子
推荐免费Vue基础教程视频:【狂神说Java】Vue最新快速上手教程通俗易懂_哔哩哔哩_bilibili
Vue笔记代码下载地址:
蓝奏云:下载地址 密码:joker
百度云:下载地址 提取码:gwam
嵌套路由
嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。同样,URL中各段动态路径也按照某种结构对应嵌套的各层组件,
1 | /user/johnny/profile /user/johnny/posts |
-
用户信息组件,在views/user目录创建一个名为Profile.vue的视图组件
1
2
3
4
5
6
7
8
9
10
11
12
13<template>
<h1>个人信息</h1>
</template>
<script>
export default {
name: "UserProfile"
}
</script>
<style scoped>
</style> -
用户列表组件,在views/user目录创建一个名为List.vue的视图组件
1
2
3
4
5
6
7
8
9
10
11
12
13<template>
<h1>用户列表</h1>
</template>
<script>
export default {
name: "UserList"
}
</script>
<style scoped>
</style> -
配置嵌套路由修改router目录下的index.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
56
57
58
59
60
61
62
63<template>
<div>
<el-container>
<el-aside width="200px">
<el-menu :default-openeds="['1']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
<el-menu-item-group>
<el-menu-item index="1-1">
<router-link to="/user/profile">个人信息</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<router-link to="/user/list">用户列表</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
<el-menu-item-group>
<el-menu-item index="2-1">分类管理</el-menu-item>
<el-menu-item index="2-2">内容列表</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px;">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-header>
<el-main>
<router-view/>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped lang="scss">
.el-header{
background-color: #B4C0D1;
color: #333;
line-height: 60px;
}
.el-aside{
color: #333;
}
</style> -
修改router文件夹下的index.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
29import Vue from 'vue'
import Router from 'vue-router'
import Main from '../views/Main'
import Login from '../views/Login'
import UserList from '../views/user/List'
import UserProfile from '../views/user/Profile'
Vue.use(Router)
export default new Router({
routes:[
{
path: '/main',
component: Main,// 嵌套路由
children: [
{path: '/user/profile',component: UserProfile},
{path: '/user/list',component: UserList}
]
},
{
path: '/login',
component: Login
}
]
}); -
运行测试
测试地址:hello-vue
参数传递及重定向
-
修改
Main.vue
,添加参数传递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<template>
<div>
<el-container>
<el-aside width="200px">
<el-menu :default-openeds="['1']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
<el-menu-item-group>
<el-menu-item index="1-1">
<!-- 参数传递 name: 传组件名 params 传递参数 需要对象-->
<router-link :to="{name: 'UserProfile',params:{id:1}}">个人信息</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<router-link to="/user/list">用户列表</router-link>
</el-menu-item>
<el-menu-item index="1-3">
<router-link to="/goHome">回到首页</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
<el-menu-item-group>
<el-menu-item index="2-1">分类管理</el-menu-item>
<el-menu-item index="2-2">内容列表</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px;">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>{{name}}</span>
</el-header>
<el-main>
<router-view/>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
props: ['name'],
name: "Main"
}
</script>
<style scoped lang="scss">
.el-header{
background-color: #B4C0D1;
color: #333;
line-height: 60px;
}
.el-aside{
color: #333;
}
</style> -
修改router文件下
index.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
35import Vue from 'vue'
import Router from 'vue-router'
import Main from '../views/Main'
import Login from '../views/Login'
import UserList from '../views/user/List'
import UserProfile from '../views/user/Profile'
Vue.use(Router)
export default new Router({
routes:[
{
path: '/main/:name',
component: Main,// 嵌套路由
props: true,
children: [
// name: 必须在单引号内 props: true 解耦
{path: '/user/profile/:id',name: 'UserProfile',component: UserProfile,props: true},
{path: '/user/list',component: UserList}
]
},
{
path: '/login',
component: Login
},{
// 重定向
path: '/goHome',
redirect: '/main'
}
]
}); -
修改
Profile.vue
,接收参数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<template>
<!-- 展示内容必须在标签内 -->
<div>
<h1>个人信息</h1>
<!-- 接收参数方式1-->
id:{{$route.params.id}}
<!-- 接收参数方式2-->
id:{{id}}
</div>
</template>
<script>
export default {
//接收参数方式2
props: ['id'],
name: "UserProfile"
}
</script>
<style scoped>
</style> -
修改
Login.vue
,将登录用户名传递到首页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<template>
<div>
<el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
<h3 class="login-title">欢迎登录</h3>
<el-form-item label="账号" prop="username">
<el-input type="text" placeholder="请输入账号" v-model="form.username"/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" placeholder="请输入密码" v-model="form.password"/>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
</el-form-item>
</el-form>
<el-dialog
title="温馨提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose">
<span>请输入账号和密码</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return {
form: {
username : '',
password : ''
},
// 表单验证 需要在el-form-item元素中增加prop属性
rules: {
username: [
{required: true,message: '账号不能为空',trigger: 'blur'}
],
password: [
{required: true,message: '密码不能为空', trigger: 'blur'}
]
},
// 对话框显示和隐藏
dialogVisible: false
}
},
methods: {
onSubmit(formName){
// 表单绑定验证
this.$refs[formName].validate((valid) => {
if(valid) {
// 使用 vue-router 路由到指定页面 该方式称为编程式导航
this.$router.push("/main/"+this.form.username);
}else{
this.dialogVisible = true;
return false;
}
});
}
}
}
</script>
<style scoped>
.login-box {
border: 1px solid #DCDFE6;
width: 350px;
margin: 180px auto;
padding: 35px 35px 15px 35px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
box-shadow: 0 0 25px #909399;
}
.login-title{
text-align: center;
margin: 0 auto 40px auto;
color: #303133;
}
</style> -
运行测试
测试地址:hello-vue
404和路由钩子
路由模式和404
路由模式有两种
- hash:路径带#号,如:http://localhost:8099/#/login
- history:路径不带#号,如:http://localhost:8099/login
修改路由配置,代码如下:
1 | export default new Router({ |
处理404创建一个名为NotFound.vue
的视图组件,代码如下
1 | <template> |
修改router文件夹下的index.js
1 | import Vue from 'vue' |
路由钩子与异步请求
beforeRouteEnter
:在进入路由前执行
beforeRouteLeave
:在离开路由前执行
修改Profile.vue
1 | <template> |
参数说明:
- to:路由将要跳转的路径信息
- from:路径跳转前的路径信息
- next:路由的控制参数
next()
跳入下一个页面next('/path')
改变路由的跳转方向,使其跳到另一个路由next(false)
返回原来的页面next((vm)=>{})
仅在beforeRouteEnter
中可用,vm是组件实例
钩子函数中使用异步请求
-
安装Axios
npm install --save axios vue-axios
-
main.js
引用Axios1
2
3
4// Axios
import axios from 'axios';
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios) -
在static下新建mock文件夹,在mock下新建
data.json
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{
"name":"Joker大雄",
"url": "http://jokerdig.com",
"page": "1",
"isNonProfit":"true",
"address": {
"street": "南稍门",
"city":"陕西西安",
"country": "中国"
},
"links": [
{
"name": "哔哩哔哩",
"url": "https://www.bilibili.com/"
},
{
"name": "Bing",
"url": "https://cn.bing.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
} -
修改
Profile.vue
文件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<template>
<!-- 展示内容必须在标签内 -->
<div>
<h1>个人信息</h1>
<!-- 接收参数方式1-->
id:{{$route.params.id}}
<!-- 接收参数方式2-->
id:{{id}}
</div>
</template>
<script>
export default {
//接收参数方式2
props: ['id'],
name: "UserProfile",
// 路由钩子
// 进入前执行
beforeRouteEnter: (to,from,next)=>{
console.log('进入路由前');
next(vm=>{
vm.getData(); // 进入之前执行方法
});
},
// 离开前执行
beforeRouteLeave: (to,from,next)=>{
console.log('离开路由前');
next();
},
methods: {
getData: function(){
this.axios({
method: 'get',
// 这里是将mode改为history后的访问地址
url: 'http://localhost:8099/static/mock/data.json'
}).then(function (response){
console.log(response)
});
}
}
}
</script>
<style scoped>
</style> -
运行测试
1
2
3
4
5
6
7
8
9
10
11控制台显示:
进入路由前
Profile.vue?5da6:37
Object
config: {transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}
data: {name: 'Joker大雄', url: 'http://jokerdig.com', page: '1', isNonProfit: 'true', address: {…}, …}
headers: {accept-ranges: 'bytes', content-length: '443', content-type: 'application/json; charset=UTF-8', date: 'Fri, 08 Jul 2022 06:07:58 GMT', etag: 'W/"1bb-k3q4Fi2fLrs6JHFRVK6Xr9nXKU8"', …}
request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status: 200
statusText: "OK"
[[Prototype]]: Object
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hey,Joker!
评论
ValineTwikoo