vue的动态路由笔记

96 阅读7分钟

动态路由

根据用户的权限信息、动态的添加路由(而不是一次性添加所有)

  • 目的:主要是有一些页面,因为一些人是没有权限查看的,但是如果也为这些没有权限的人注册路由的时候,虽然他不能从菜单进入,但可以通过网路地址进行直接跳转,因此会产生信息不安全。

  • 优点

      1. 权限管理:在后台管理系统中,不同的用户可鞥会有不同的访问权限。例如、管理员可以访问所有页面、而普通用户可能只能访问部分页面。通过使用动态路由、可以根据用户的角色权限动态生成路由表、这样用户就只能访问到他们有权访问的页面。
      2. 代码分割和懒加载:如果你的应用有很多页面】那么一开始就加载所有的页面可能会导致应用的首次加载时间过长。通过使用动态路由、可以实现路由组件的懒加载、即值有当用户访问某个路由时、才加载对应的组件。这样可以加快首次加载的速度。
      3. 更好对用户体验::动态路由允许你创建更加丰富和互动的用户界面。例如,你可以根据路由参 数显示不同的内容,或者在用户导航到新的页面时保留某些状态。这些都可以提供更好的用户 体验。
      4. 更好的可维护性和可扩展性:由于路由表是动态生成的,因此在添加或删除页面时,你只需要 修改对应的路由配置,而不需要修改路由表。这使得代码更易于维护,并且在项目扩展时更加 灵活。

实现方案

通过菜单(menu)进行动态的路由管理

优点

  1. 结构清晰:通过基于菜单进行动态路由管理,可以使系统的路由结构和导航菜单高度一致,更 加直观和易于理解。不同菜单项对应不同的页面,用户可以通过导航菜单直接访问到对应的页 面,提高了系统的可用性和可操作性。
  2. 可扩展性:基于菜单的动态路由管理可以轻松地扩展和新增菜单项和页面,而不需要频繁地修 改和维护路由配置。这样在系统需要增加新的功能或页面时,可以直接在菜单配置中新增对应 的菜单项,而无需修改路由配置,提高了系统的可维护性和扩展性。
  3. 权限控制:通过基于菜单的动态路由管理,可以方便地进行权限控制,确保用户只能访问其所 具有权限的页面。在菜单配置中可以添加权限字段,根据用户权限动态生成菜单和对应的路 由,以达到权限控制的目的。

劣势

  1. 数据传递复杂:在基于菜单的动态路由管理中,菜单项和路由之间需要进行数据的传递和同 步,以保持菜单和路由的一致性。这会涉及到一些额外的工作,如菜单项与路由的映射关系维 护、菜单与路由数据的同步等,增加了一定的开发复杂性。
  2. 前端转发增加:基于菜单的动态路由管理需要前端进行页面之间的跳转和转发,用户首先点击 菜单项,然后前端进行路由跳转至对应的页面。这会增加前端路由处理的工作量和复杂性。

实现关键:

  1. 需要后台定菜单数据结构,并与路由进行关联,通常可以使用数据库或者接口的数据结构来进行存储菜单信息。
  2. 在前端启动的时候,需要从后端拿到完整的菜单、和用户的菜单并且保存值状态进行管理或者Vue的实例中,并且有些需要保存到本地。
  3. 然后根据用户彩单数据进行动态生成路由。然后使用Vue-Router的addRouter方法进行动态的注册。在进行注册的时候,需要注意必须传入的菜单需要path和Component参数。
  4. 根据菜单数据生成导航菜单,可以使用Vue的渲染函数或组件来生成具有层级结构的导航菜 单。

下面是coderwhy老师一个案例如果进行动态路由的注册过程案例:

菜单:

image-20230904200946673.png

创建所有菜单下面的页面

image.png

并且创建相应的路由文件,用来对路由进行注册时候进行使用,内容是(这是其中一个页面,其他页面类似。

const role = () => import('@/view/main/system/role/role.vue')
export default {
  path: '/main/system/role',
  name: 'role',
  component: role,
  children: []
}

因为所要创建的页面文件过多,这里推荐老师自己写的一个插件,非常好用,可以快速生成这些格式的文件。

coderwhy插件

安装 npm install coderwhy -g

npm地址:coderwhy - npm (npmjs.com)

这个包的作用是:创建出视图界面文件的同时创建出对应的路由文件,并且在路由文 件中将其关联起来

使用:

//使用示例
coderwhy add3page_setup menu -d src/views/main/system/menu

coderwhy : 这是CLI工具的名称,用于执行各种操作,如创建项目,添加页面,添加 组件等。

add3page_setup : 这是coderwhy CLI的一个命令,它可能用于添加一个使用Vue 3 setup语法的页面(add3的意思是添加Vue3的代码(同理add2就是vue2的代码了),如 果不加上setup的话,他创建出来的页面是Vue3不使用setup语法糖的形式)。

menu:这个是自动化创建的文件名字

-d :这是一个命令行选项,通常用于指定目标目录。在这个上下文中,它是用于指定 新创建的页面应该放在哪个目录下。

@/views/main/system/menu : 这是目标目录的路径,表示你想要在这个路径下创建 新的页面。(这里的路径具体根据自己的项目结构进行填写

创建完毕就可以进行得到这些菜单所需的所有页面、和需要动态注册的路由文件。

处理动态路由文件

const localRouter: RouteRecordRaw[] = [] //存放所有的刚刚新写页面路由 const files: Record<string, any> = import.meta.glob('../view/main/**/*.ts', {
    eager: true
  })
//{eager: true} : 这是一个选项对象,传递给 import.meta.glob 函数。 eager 选项设
//置为 true 时,Vite 会在初始化时立即导入匹配的模块,而不是等到你实际调用返回
//的函数时再导入。这对于确保所有模块都已准备就绪,无论是否已经引用过它们,是
//很有用的
  // console.log(files)
  for (const f in files) {
    const module = files[f]
    localRouter.push(module.default)
  }

import.meta.glob('../view/main/ */ .ts', { eager: true })返回的数据:

RouteRecordRaw[] :这是vue-Router官方提供的类型,导入即可用

Record 是 TypeScript 的一个工具类型,它创建 一个对象类型,该对象的键是字符串,值的类型是 any ,为什么要写这个工具类型, 那是因为默认情况下第二个参数的类型是 unknown ,而我们并不希望是这个。Record 是 TypeScript 的一个工具类型,它创建 一个对象类型,该对象的键是字符串,值的类型是 any ,为什么要写这个工具类型, 那是因为默认情况下第二个参数的类型是 unknown ,而我们并不希望是这个。

image.png

对用户的菜单权限进行路由动态注册

export function mapMenusRouter(userMenus: any[]) {
  // 动态添加路由
​
  // 將动态路由添加到localRouter
//根据菜单的层级嵌套来进行多层级遍历
  for (let i = 0; i <= userMenus.length - 1; i++) {
    // 第一层路由
    if (!localRouter.find((item) => item?.path === userMenus[i].url)) {
        //这里是注册第一层级的用户路由,这里做的主要是对第一次进行重定向,因为系项目中第一级菜单没有实际页面,点击后应该不会跳转该路径,因此对其进行重定向,当进入这个路径的时候,就自动跳入到该二级路径下的第一个页面。
      router.addRoute('main', {
        path: userMenus[i].url,
        redirect: userMenus[i].children[0].url
      })
    }
​
    for (const menu of userMenus[i].children) {
      const route = localRouter.find((item) => item?.path === menu.url)
      // 第二层路由
      if (route) {
        mapRouter.push(route)
          //这里主要是第一登入的时候,第一次需要跳入的路径。
        if (!firstPage) {
          firstPage = menu
        }
      }
    }
  }
    //最后返回用户有权限访问的菜单
  return mapRouter
}