十分钟学会动态路由

发布于:2022-12-30 ⋅ 阅读:(364) ⋅ 点赞:(0)

目录

1.理解动态路由思路分析

介绍

思路分析

图表分析

2.具体实现方式

(1)拆分静态路由表和动态路由表

理解动态和静态路由

工作原理 

具体实现 

(2)创建功能页面组件并配置路由

设置路由

小结

(3)模块化管理动态路由

分析

思路

文件内容

router/index.js

(4)左侧菜单自动生成的逻辑

问题1:为什么路由表里添加了新路由就会显示到左侧

问题2:菜单中的title和图标从哪里来?

(5)动态设置标题

分析

设置页面标题

代码

小结


1.理解动态路由思路分析

介绍

动态路由,要实现的最终效果是:不同用户登陆进来时,显示出来的菜单功能是不同的

思路分析

1用户A登录成功之后,后端返回A的权限信息:能访问的页面的标识集合
2根据上一步得到的标识集合,在本地的项目页面中,选出用户A能访问的页面集合
3加上合法用户都能访问的页面集合(俗称静态页面),一起构成

图表分析

动态生成路由表

2.具体实现方式

(1)拆分静态路由表和动态路由表

理解动态和静态路由

静态路由表:不需要做权限控制的路由,每个用户都可以正常访问。
动态路由表:需要做权限控制的路由,用户如果权限不一致访问到的路由也不一样。

工作原理 

用户登录之后,根据后端返回的数据表示携带的功能不同,动态生成路由配置

具体实现 

进入 router/index.js文件,做两处修改:

第一个就是补充一个动态路由表asyncRoutes
第二个就是将动态和静态合并在一起

// 省略其他...
// 动态路由表,项目中不同的用户可以访问不同的功能
+ export const asyncRoutes = [
  // 先空着这里,后面来补充功能
]

// 静态路由表,项目中每个用户都可以访问的功能
export const constantRoutes = [
  // 省略....
]

const createRouter = () => new Router({
  // 控制路由滚动行为  滚动到顶部
  scrollBehavior: () => ({ y: 0 }),
  // 组合到一起组成路由表
+ routes: [...constantRoutes, ...asyncRoutes]
})

(2)创建功能页面组件并配置路由

在 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的子路由。

(3)模块化管理动态路由

分析

前面已经定义了动态路由的方式,直接继续往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 和 默认导出


router/index.js

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] // 临时合并所有的路由
})

(4)左侧菜单自动生成的逻辑

问题1:为什么路由表里添加了新路由就会显示到左侧

答案就在  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、项目左侧的菜单时根据完整的路由表遍历出来的

问题2:菜单中的title和图标从哪里来?


负责菜单标题渲染的是meta属性中的title属性

负责图标渲染的是meta中的icon属性

(5)动态设置标题

分析

进去不同的页面,显示不同的标题

通过设置路由导航守卫来设置。
在不同页面中独立设置标题,把标题信息保存在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()
})

小结

  • 导航守卫可以写多个
  • 设置标题是    document.title='xxxx'
     

本文含有隐藏内容,请 开通VIP 后查看