目标
删除基础模板中附带的多余页面
**注意
**这里的动态路由并不是 路由传参的动态路由
了解完成路由设计之后,我们对当前的路由进行一下整理
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 page must be placed at the end !!!
{
path: '*', redirect: '/404', hidden: true }
]
目标
: 快速搭建人资项目的常规业务模块
├── dashboard # 首页
├── login # 登录
├── 404 # 404
├── departments # 组织架构
├── employees # 员工
├── setting # 公司设置
├── salarys # 工资
├── social # 社保
├── attendances # 考勤
├── approvals # 审批
├── permission # 权限管理
index.vue
**,作为每个模块的主页<template>
<div class="dashboard-container">
<div class="app-container">
<h2>
员工
</h2>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
$ mkdir departments employees setting salarys social attendances approvals permission
├── router # 路由目录
├── index.js # 路由主文件
├── modules # 模块目录
├── departments.js # 组织架构
├── employees.js # 员工
├── setting.js # 公司设置
├── salarys.js # 工资
├── social.js # 社保
├── attendances.js # 考勤
├── approvals.js # 审批
├── permission.js # 权限管理
$ touch departments.js employees.js setting.js salarys.js salarys.js social.js attendances.js approvals.js permission.js
// 导出属于员工的路由规则
import Layout from '@/layout'
// { path: '', component: '' }
// 每个子模块 其实 都是外层是layout 组件位于layout的二级路由里面
export default {
path: '/employees', // 路径
name: 'employees', // 给路由规则加一个name
component: Layout, // 组件
// 配置二级路的路由表
children: [{
path: '', // 这里当二级路由的path什么都不写的时候 表示该路由为当前二级路由的默认路由
component: () => import('@/views/employees'),
// 路由元信息 其实就是存储数据的对象 我们可以在这里放置一些信息
meta: {
title: '员工管理' // meta属性的里面的属性 随意定义 但是这里为什么要用title呢, 因为左侧导航会读取我们的路由里的meta里面的title作为显示菜单名称
}
}]
}
// 当你的访问地址 是 /employees的时候 layout组件会显示 此时 你的二级路由的默认组件 也会显示
上述代码中,我们用到了meta属性,该属性为一个对象,里面可放置自定义属性,主要用于读取一些配置和参数,并且值得**
注意
的是:我们的meta写了二级默认路由上面,而不是一级路由,因为当存在二级路由的时候,访问当前路由信息访问的就是二级默认路由
**
目标
: 将静态路由和动态路由的路由表进行临时合并
什么叫临时合并?
在第一个小节中,我们讲过了,动态路由是需要权限进行访问的,但是权限的动态路由访问是很复杂的,我们稍后在进行讲解,所以为了更好地看到效果,我们可以先将 静态路由和动态路由进行合并
src/router/index.js
// 引入多个模块的规则
import approvalsRouter from './modules/approvals'
import departmentsRouter from './modules/departments'
import employeesRouter from './modules/employees'
import permissionRouter from './modules/permission'
import attendancesRouter from './modules/attendances'
import salarysRouter from './modules/salarys'
import settingRouter from './modules/setting'
import socialRouter from './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] // 临时合并所有的路由
})
目标
解析左侧菜单的显示逻辑, 设置左侧导航菜单的图标内容
左侧菜单 的形成!!!
是由 $router.options.routes(路由表) 经过 v-for 循环 得到的
如果只有一个子路由或没有路由则是一级菜单,多个子路由则是二级菜单
本节注意
:通过代码发现,当路由中的属性**hidden
**为true时,表示该路由不显示在左侧菜单中
与此同时,我们发现左侧菜单并不协调,是因为缺少图标。在本项目中,我们的图标采用了SVG的组件
<template>
<div v-if="!item.hidden"> // 这个判定 是判断 hidden= true 时不显示
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> //这里也有一个判定
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
</el-menu-item>
</app-link>
</template>
<!-- <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</el-submenu> -->
</div>
</template>
src/icons/svg
**目录下该资源已经在菜单svg目录中提供,请将该目录下的所有svg放到**
src/icons/svg
**目录下
├── dashboard # dashboard
├── departments # tree
├── employees # people
├── setting # setting
├── salarys # money
├── social # table
├── attendances # skill
├── approvals # tree-table
├── permission # lock
函数式组件: 没有data状态,没有响应式数据,只会接收props属性, 没有this, 他就是一个函数
functional为true,表示该组件为一个函数式组件
这个 src 下 layout components sidebar 下的 item.vue 就是一个 函数式组件
<script>
export default {
name: 'MenuItem',
functional: true,
//functional为true,表示该组件为一个函数式组件
// 函数式组件: 没有data状态,没有响应式数据,只会接收props属性, 没有this, 他就是一个函数
props: {
icon: {
type: String,
default: ''
},
title: {
type: String,
default: ''
}
},
render(h, context) {
const {
icon, title } = context.props
const vnodes = []
if (icon) {
if (icon.includes('el-icon')) {
vnodes.push(<i class={
[icon, 'sub-el-icon']} />)
} else {
vnodes.push(<svg-icon icon-class={
icon}/>)
}
}
if (title) {
vnodes.push(<span slot='title'>{
(title)}</span>)
}
return vnodes
}
}
</script>
<style scoped>
.sub-el-icon {
color: currentColor;
width: 1em;
height: 1em;
}
</style>