赞
踩
目录
动态路由,要实现的最终效果是:不同用户登陆进来时,显示出来的菜单功能是不同的
1用户A登录成功之后,后端返回A的权限信息:能访问的页面的标识集合
2根据上一步得到的标识集合,在本地的项目页面中,选出用户A能访问的页面集合
3加上合法用户都能访问的页面集合(俗称静态页面),一起构成
动态生成路由表
静态路由表:不需要做权限控制的路由,每个用户都可以正常访问。
动态路由表:需要做权限控制的路由,用户如果权限不一致访问到的路由也不一样。
用户登录之后,根据后端返回的数据表示携带的功能不同,动态生成路由配置
进入 router/index.js文件,做两处修改:
第一个就是补充一个动态路由表asyncRoutes
第二个就是将动态和静态合并在一起
- // 省略其他...
- // 动态路由表,项目中不同的用户可以访问不同的功能
- + export const asyncRoutes = [
- // 先空着这里,后面来补充功能
- ]
-
- // 静态路由表,项目中每个用户都可以访问的功能
- export const constantRoutes = [
- // 省略....
- ]
-
- const createRouter = () => new Router({
- // 控制路由滚动行为 滚动到顶部
- scrollBehavior: () => ({ y: 0 }),
- // 组合到一起组成路由表
- + routes: [...constantRoutes, ...asyncRoutes]
- })
在 src/views/ 的文件下配置功能页面组件
这里我们要嵌套路由,就是让我们在显示功能页面(以 employees为例)的同时还能看到 项目的整体架子(以layout为例),我们可以将它设置为layout的二级路由
- {
- path: '/employees',
- component: Layout,
- children: [
- {
- path: '', // 作为默认渲染路由
- name: 'employees',
- component: () => import('@/views/employees/employees.vue'),
- meta: { title: 'Employees', icon: 'employees' }
- }
- ]
- }
模仿原来首页的写法,实现了Layout架子的渲染。注意到:把二级路由的path选项置空,作为默认渲染路由。
原来的写法是:不使用,用上面的那个代码
- export const asyncRoutes = [
- {
- path: '/employees',
- name: 'employees',
- component: () => import('@/views/employees/employees.vue'),
- meta: { title: 'Employees', icon: 'employees' }
- }
- ]
要想所有的功能页面中都包含左侧菜单及顶部导航条,需要将它们设置成layout的子路由。
前面已经定义了动态路由的方式,直接继续往asyncRoutes表里继续添加定义就可以实现,但有个问题,若功能越来越负责,可能动态管理的路由数量会很多,那 router/index.js文件会变的非常大,不好维护。
为了解决这个问题,我们对动态的路由进行物理目录拆分,实现模块化管理
把每一个路由配置单独写在一个文件中,然后再统一导入使用
在src/router下补充创建modules文件夹,并创建自己需要的几个.js文件。我们知道路由模块和业务模块是一一对应的,所以我们需要创建相等数量的路由模块文件,具体如下:
- ├── router # 路由目录
- ├── index.js # 路由主文件
- ├── modules # 模块目录
- ├── departments.js # 组织架构
- ├── employees.js # 员工
- ├── settings.js # 公司设置
- ├── salarys.js # 工资
- ├── social_securitys.js # 社保
- ├── attendances.js # 考勤
- ├── approvals.js # 审批
- ├── permissions.js # 权限管理
以router/modules/employees.js为例,它的代码是:
- import Layout from '@/layout'
- // Layout组件中包含
- export default {
- path: '/employees', // 路径
- component: Layout, // 组件
- children: [{
- name: 'employees', // 给路由规则加一个name
- path: '', // 这里当二级路由的path什么都不写的时候 表示当前路由为默认路由直接渲染对应组件
- component: () => import('@/views/employees/employees.vue'),
- // 路由元信息 其实就是存储数据的对象 我们可以在这里放置一些信息
- meta: { title: '员工管理' }
- }]
- }
注意上边的导入 layout 和 默认导出
- import employeesRouter from './modules/employees'
- const asyncRoutes = [
- employeesRouter
- ]
-
- const createRouter = () => new Router({
- scrollBehavior: () => ({ y: 0 }), // 管理滚动行为 如果出现滚动 切换就让 让页面回到顶部
- routes: [...constantRoutes, ...asyncRoutes] // 临时合并所有的路由
- })
最终完成的代码,如下
- // 引入多个动态路由模块
- 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/settings'
- import socialRouter from './modules/social_securitys'
-
- // 省略其它...
-
- // 组合动态路由模块
- export const asyncRoutes = [
- approvalsRouter,
- departmentsRouter,
- employeesRouter,
- permissionRouter,
- attendancesRouter,
- salarysRouter,
- settingRouter,
- socialRouter
- ]
- const createRouter = () => new Router({
- scrollBehavior: () => ({ y: 0 }), // 管理滚动行为 如果出现滚动 切换就让 让页面回到顶部
- routes: [...constantRoutes, ...asyncRoutes] // 临时合并所有的路由
- })
答案就在 layout/components/SideBar/index.vue 文件中,下面摘录核心代码如下:
- <template>
- <sidebar-item
- v-for="route in routes"
- :key="route.path"
- :item="route"
- :base-path="route.path"
- />
- </template>
-
- <script>
- export default {
- computed: {
- routes() {
- // this.$router.options.routes可以拿到路由配置中的路由表数据
- return this.$router.options.routes
- }
- }
- }
- </script>
通过分析源码我们得知
1、this.$router.options.routes 可以拿到完整的路由表数据
2、项目左侧的菜单时根据完整的路由表遍历出来的
负责菜单标题渲染的是meta属性中的title属性
负责图标渲染的是meta中的icon属性
进去不同的页面,显示不同的标题
通过设置路由导航守卫来设置。
在不同页面中独立设置标题,把标题信息保存在meta中;
在路由跳转时:在路由前置守卫中,获取title,并设置
document.title = '标题内容'
在src/permission.js中
1.引入工具方法 getPageTitle
import getPageTitle from '@/utils/get-page-title'
2.在路由守卫中调用
补充一个路由守卫
- router.beforeEach((to, from, next) => {
- document.title = getPageTitle(to.meta.title)
- next()
- })
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。