路由配置
路由配置介绍
熟悉静态路由和动态路由的概念
- 静态路由:提前写死的路由配置(只要打开页面就可以访问的路由)
- 动态路由:只有该用户拥有这个路由模块权限的时候才可以访问路由(由用户的权限控制)
- 动态路由的权限是由用户相关的数据决定的
整理路由配置
**目标**
删除基础模板中附带的多余页面并且删除多余的路由配置
- 删除多余的路由配置
**src/router/index.js**
// 静态路由表 => 静态路由(不需要权限即可访问的)
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: 'Dashboard', icon: 'dashboard' }
}
]
},
// 没有匹配到的页面, 走404
// { path: '*', redirect: '/404', hidden: true }
]
上面代码,我们只对【登录页/404/主页】进行了保留,并且我们发现,删除了其他页面之后,左侧导航菜单的数据也只剩下了首页
注意:
- 路由映射会影响左侧菜单的显示
- 路由映射中如果包含hidden:true属性,那么左侧就不显示该路由菜单,否则就显示
搭建业务模块页面
**目标**
: 快速搭建 - 人资项目的常规业务模块 - 主页面
├──views
├── approvals # 审批
├── attendances # 考勤
├── dashboard # 首页 -- 已有
├── departments # 组织架构
├── employees # 员工
├── login # 登录 -- 已有
├── permission # 权限管理
├── salarys # 工资
├── setting # 公司设置
├── social # 社保
├── 404 # 404 -- 已有
- 通过命令快速创建相关目录
mkdir approvals attendances departments employees permission salarys setting social
- 每个模块的内容,可以先按照标准的模板建立,如下所示
<template>
<div class="dashboard-container">
<div class="app-container">
<h2>
首页
</h2>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped>
</style>
总结,如何快速的创建多个文件夹?mkdir 文件夹名称(多个名称空格隔开)
配置模块路由规则
目标:配置路由规则
- 我们这边会拆分出来, 每个模块一个路由规则, 以组织架构 departments 为例
// 首页模块
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}
]
},
// 组织架构模块
{
path: '/departments',
component: Layout,
children: [
{
path: '',
name: 'departments',
component: () => import('@/views/departments'),
meta: { title: '组织架构', icon: 'dashboard' }
}
]
},
总结
- 左侧菜单一级路由组件都是Layout
- 右侧区域显示的组件实际上是二级路由
注意:如果children配置的子路由的path如果是空字符串,那么默认就显示该二级路由
为什么要这样配置?为了进一步拆分路由模块(项目规模变大之后,拆分更容易维护)
左侧菜单逻辑分析
目标
:熟悉左侧菜单的渲染逻辑
**src/layout/components/Sidebar/SidebarItem.vue**
- 只要配了一个规则, 就多出来一个菜单, 是因为菜单的项, 是遍历路由规则动态渲染出来的
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
</el-menu>
computed: {
routes() {
// this.$router.options.routes 代表的是配置的路由映射
// 这个API是由vue-router提供
return this.$router.options.routes
},
}
- 路由规则上, 可以配置一个 hidden 属性, 配置 true, 就是将来不渲染菜单(除了hidden之外也与children属性有关)
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
- 这里菜单的渲染, 处理了
一级导航菜单
和二级导航菜单
, 二级导航我们这边不需要,可以注释掉
<template>
<div v-if="!item.hidden">
总结:通过vue-router的api获取所有的路由映射数组,动态遍历形成左侧菜单,通过hidden属性控制路由映射是否显示在左侧菜单列表中。
关于左侧菜单的结构
- 菜单显示的条件:hidden和children共同决定
- 组件的嵌套关系
-
router-link标签是由
动态组件
component渲染出来 -
动态组件单独再分析
-
<el-menu>
<router-link :to='to'>
<el-menu-item>
<!-- item组件用于显示菜单的图标和标题文本 -->
<item></item>
</el-menu-item>
</router-link>
</el-menu>
总结:
- 单个菜单实际上是 Item.vue 组件,组件显示的数据来源是二级路由映射的对象
- 路由的跳转由app-link组件控制,目前可以暂且理解router-link的作用
- 接下来分析AppLink组件内部的实现:动态组件
template标签用法
目标:熟悉template标签的用法
<div v-if="isShow">tom</div>
<div v-if="isShow">jerry</div>
<!-- 方便统一控制一组标签,而template标签本身不会渲染出来 -->
<template v-if="isShow">
<div>tom</div>
<div>jerry</div>
</template>
总结:template标签可以方便的控制一组标签的效果。
动态组件基本用法
目标:熟悉动态组件的基本使用规则
import MyInfo from './MyInfo.vue'
import MyMsg from './MyMsg.vue'
export default {
name: 'Dashboard',
components: {
MyInfo,
MyMsg
},
data () {
return {
isShow: true,
currentComponent: 'my-msg'
}
},
<!-- 动态组件: currentComponent的属性值是那个组件名称就显示那个组件-->
<!-- 动态组件方便进行一类组件的缓存控制 -->
<keep-alive>
<component :is="currentComponent" />
</keep-alive>
<button @click="currentComponent="my-info"">Info</button>
<button @click="currentComponent="my-msg"">Msg</button>
总结:
- is的值是要渲染的组件的名称,最终渲染的结果仅仅是组件本身的模板,不会渲染出component标签
- 动态组件方便进行一类组件的缓存
- 动态组件的is属性值支持原生HTML元素
<!-- 动态组件的is属性值支持原生的DOM标签 -->
<!-- component标签上可以通过属性绑定给动态组件或者HTML标签绑定属性 -->
<component :is="currentComponent" :href="curl" :class="{active: true}">跳转</component>
<!-- vue在做属性绑定时,可以一次性通过一个对象绑定多个属性 -->
<component :is="currentComponent" v-bind="obj">跳转</component>
data () {
return {
isShow: true,
// currentComponent: 'my-msg'
currentComponent: 'a',
curl: 'http://itcast.cn',
obj: {
href: 'http://itcast.cn',
class: 'active'
}
}
},
总结:
- 动态组件的is属性值支持原生HTML元素
- component标签上可以通过属性绑定给动态组件或者HTML标签绑定属性
- vue在做属性绑定时,可以一次性通过一个对象绑定多个属性(
v-bind='obj'
)
总结:app-link组件的作用是在el-menu-item组件的外面包裹一个router-link标签
- 组件的插槽基本使用
- 动态组件
- v-bind可以直接赋值一个对象,将对象中的每一个属性进行动态绑定
配置菜单文字和icon图标
目标
: 配置菜单文字 和 菜单图标
- 拷贝svg图标到项目中: 该资源已经在资料svg目录中提供,请将该目录下的所有svg放到
**src/icons/svg**
目录下 - 修改icon名字: 具体的icon名称可参考线上地址
{
path: '/departments',
component: Layout,
children: [
{
path: '',
name: 'departments',
component: () => import('@/views/departments'),
meta: { title: '组织架构', icon: 'tree' }
}
]
},
- 模块对应icon参照表
├── dashboard # dashboard
├── departments # tree
├── employees # people
├── setting # setting
├── salarys # money
├── social # table
├── attendances # skill
├── approvals # tree-table
├── permission # lock
总结:
- 把svg图标文件拷贝到 icons/svg目录里面
- 修改路由映射的meta中的icon属性的值为svg文件名称
拆分路由模块
目标
: 新建拆分路由模块按刚才的方式, 成功新增了一个路由模块, 但是如果所有的路由全都写在一个文件中肯定不合适, 所以要拆模块
- 业务路由模块目录结构
├── router # 路由目录
├── index.js # 路由主文件
├── modules # 模块目录
├── approvals.js # 审批 图标: tree-table
├── attendances.js # 考勤 图标: skill
├── departments.js # 组织架构 图标: tree
├── employees.js # 员工 图标: people
├── permission.js # 权限管理 图标: lock
├── salarys.js # 工资 图标: money
├── setting.js # 角色管理 图标: setting
├── social.js # 社保 图标: table
- 快速创建文件命令
touch approvals.js attendances.js departments.js employees.js permission.js setting.js salarys.js social.js
- 重构文件内容
// 组织架构模块
import Layout from '@/layout'
export default {
path: '/departments',
component: Layout,
children: [
{
path: '',
name: 'departments',
component: () => import('@/views/departments'),
meta: { title: '组织架构', icon: 'tree' }
}
]
}
总结:把每一个业务模块的路由单独进行拆分然后再导入并进行配置
- 基于touch命令批量创建文件
- 拆分各个路由模块
- 创建不同模块的组件
动态路由和静态路由合并
**目标**
: 将静态路由和动态路由的路由表进行临时合并
- 什么叫临时合并?
在第一个小节中,我们讲过了,动态路由是需要权限进行访问的,但是权限的动态路由访问是比较复杂的,
我们后面再进行讲解,所以为了更好地看到效果,我们可以先将 静态路由和动态路由进行合并, 也就是默认开放所有路由权限
路由主文件
**src/router/index.js**
// 引入多个模块的规则
import approvalsRouter from '@/router/modules/approvals'
import departmentsRouter from '@/router/modules/departments'
import employeesRouter from '@/router/modules/employees'
import permissionRouter from '@/router/modules/permission'
import attendancesRouter from '@/router/modules/attendances'
import salarysRouter from '@/router/modules/salarys'
import settingRouter from '@/router/modules/setting'
import socialRouter from '@/router/modules/social'
// 动态路由表 => 动态路由(需要权限才可以访问的) 我们这里准备一个数组存放
export const asyncRoutes = [
approvalsRouter,
departmentsRouter,
employeesRouter,
permissionRouter,
attendancesRouter,
salarysRouter,
settingRouter,
socialRouter
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }), // 管理滚动行为, 让页面切换时回到顶部
routes: [...constantRoutes, ...asyncRoutes] // 临时合并动态路由和静态路由
})
总结:静态路由配置和动态路由配置分开处理
- 数组的合并写法
cosnt arr = [...arr1, ...arr2]
- 动态路由后续需要根据用户的权限进行控制
处理高亮激活
目标
:控制点击路由链接高亮左侧菜单被选中时, 会加上一个 is-active 类, 可以在
sidebar.scss
覆盖下样式
li.is-active {
background-color: #fff!important;
.svg-icon {
color: #43a7fe;
}
span {
color: #43a7fe;
}
}
总结:点中左侧菜单后,自动添加一个is-active类名,我们需要提供对应的样式即可。
注意:点中菜单高亮的行为是 Element-UI的菜单组件的行为 (is-active类名是Element-UI自动添加的)
基于路由的高亮采用:router-link-exact-active router-link-active