路由嵌套
嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如:
/user/foo/profile /user/foo/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
- 用户信息组件,在 views/user 目录下创建一个名为 Profile.vue 的视图组件;
<template>
<div>
<h1>个人信息</h1>
</div>
</template>
<script>
export default {
name: "UserProfile"
}
</script>
<style scoped>
</style>
- 用户列表组件在 views/user 目录下创建一个名为 List.vue 的视图组件;
<template>
<div>
<h1>用户列表</h1>
</div>
</template>
<script>
export default {
name: "UserList"
}
</script>
<style scoped>
</style>
- 配置嵌套路由修改 router 目录下的 index.js 路由配置文件,代码如
import 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: '/login',
component: Login
},
{
path: '/main',
component: Main,
children: [
{
path: '/user/profile',
component: UserProfile
},
{
path: '/user/list',
component: UserList
}
]
}
]
})
- 修改首页视图,我们修改 Main.vue 视图组件,此处使用了 ElementUI 布局容器组件,代码如下:
<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: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
说明:
在元素中配置了用于展示嵌套路由,主要使用个人信息展示嵌套路由内容
参数传递
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。此时我们就需要传递参数了;
组件转发
$route方式
- 修改路由配置,
- 主要是在 path 属性中增加了 :id,:name 这样的占位符
{
path: '/main',
component: Main,
children: [
{
path: '/user/profile/:id/:name',
name: 'UserProfile',
component: UserProfile
},
{
path: '/user/list',
component: UserList
}
]
}
- 传递参数
- 此时我们将 to 改为了 :to,是为了将这一属性当成对象使用,
- 注意 router-link 中的 name 属性名称一定要和路由中的name 属性名称 匹配,因为这样 Vue 才能找到对应的路由路径;
<!--name:传组件名, params:传递参数, 需要对象: v-bind-->
<router-link :to="{name:'UserProfile',params:{id:1,name:'狂神'}}">
个人信息</router-link>
- 接收参数, 在目标组件中
<div>
<h1>个人信息</h1>
{{$route.params.id}}
{{$route.params.name}}
</div>
使用 props 的方式
- 修改路由配置 , 主要增加了 props: true 属性
routes: [
{
path: '/login',
component: Login
},
{
path: '/main',
component: Main,
children: [
{
path: '/user/profile/:id/:name',
name: 'UserProfile',
component: UserProfile,
props: true
},
{
path: '/user/list',
component: UserList
}
]
}
]
- 传递参数和之前一样
- 接收参数为目标组件增加 props 属性
<div>
<h1>个人信息</h1>
{{id}}
{{name}}
</div>
组件重定向
- 重定向的意思大家都明白,但 Vue 中的重定向是作用在路径不同但组件相同的情况下,比如:
{
path: '/goHome',
redirect: '/main'
}
- 说明:这里定义了两个路径,一个是 /main ,一个是 /goHome
- 其中 /goHome 重定向到了 /main 路径,由此可以看出重定向不需要定义组件;
- 使用的话,只需要设置对应路径即可;
<el-menu-item index="1-3">
<router-link to="/goHome">回到首页</router-link>
</el-menu-item>
路由模式与 404
路由模式有两种
hash:
路径带 # 符号,如 http://localhost/#/login
- 默认为hash路由模式
export default new Router({
routes: []
})
history:
路径不带 # 符号,如 http://localhost/login
- history路由模式
export default new Router({
mode: 'history',
routes: []
})
404
- 创建一个名为 NotFound.vue 的视图组件,代码如下:
<template>
<div>
<h1>404,你的页面走丢了</h1>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
- 修改路由配置,代码如下:
import NotFound from '../views/NotFound'
export default new Router({
mode: 'history',
routes: [
{
path: '*',
component: NotFound
}
]
})
路由钩子与异步请求
路由钩子
- beforeRouteEnter:在进入路由前执
- beforeRouteLeave:在离开路由前执行
export default {
name: "UserProFile",
props: ['id','name'],
beforeRouteEnter: (to,from,next) => {
console.log('进入路由之前')
next()
},
beforeRouteLeave: (to,from,next) => {
console.log('进入路由之后')
next()
}
}
参数说明:
- to:路由将要跳转的路径信息
- from:路径跳转前的路径信息
- next:路由的控制参数
- next() 跳入下一个页面
- next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
- next(false) 返回原来的页面
- next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例
异步请求
- 安装 Axios cnpm install --save vue-axios
- main.js引用 Axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
- 准备数据 : 只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下static/mock/data.json。
{
"name": "狂神说Java",
"url": "https://blog.kuangstudy.com",
"page": 1,
"isNonProfit": true,
"address": {
"street": "含光门",
"city": "陕西西安",
"country": "中国"
},
"links": [
{
"name": "bilibili",
"url": "https://space.bilibili.com/95256449"
},
{
"name": "Java",
"url": "https://blog.kuangstudy.com"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
- 运行项目npm run dev看是否正常
- 因为cnpm可能安装失败,重新安装一下cnpm install --save vue-axios
- 在 beforeRouteEnter 中进行异步请求
export default {
name: "UserProFile",
props: ['id','name'],
beforeRouteEnter: (to,from,next) => {
console.log('进入路由之前');//加载数据
next(vm => {
vm.getData();//进入路由之前执行getData()
})
},
beforeRouteLeave: (to,from,next) => {
console.log('进入路由之后');
next()
},
methods: {
getData() {
this.axios({
method: 'get',
url: 'http://localhost:8080/static/mock/data.json'
}).then((response) => {
console.log(response)
})
}
}
}
版权声明:本文为david2000999原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。