Vu3项目-动态添加路由

154 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天

在登录成功时,拿到接口返回的用户权限对应的菜单

actions: {
   async loginAccountAction(account: IAccount) {
     // 获取用户权限对应的菜单
     const userMenusResult = await getRoleMenus(this.userInfo.role.id)
     this.userMenus = userMenusResult.data
     // 动态添加路由
     const routes = mapMenusToRoutes(this.userMenus)
     routes.forEach((route) => router.addRoute('main', route))
   }
 },

utils中添加mapMenusToRoutes函数

/**
 * 本地路由映射当前用户权限的路径
 * @param userMenus 当前用户权限的路径
 * @returns 匹配到的路径
 */
export function mapMenusToRoutes(userMenus: any[]) {
  // 1.加载项目路由
  const localRoutes = loadLocalRoutes()

  // 2.根据菜单去匹配正确的路由
  const routes: RouteRecordRaw[] = []
  // 遍历一级菜单
  for (const menu of userMenus) {
    // 遍历二级菜单
    for (const submenu of menu.children) {
      // 找到项目路由与当前用户权限拥有的对应路由
      const route = localRoutes.find((item) => item.path === submenu.url)
      if (route) {
        // 1.给route的顶层菜单增加重定向功能(但是只需要添加一次即可)
        if (!routes.find((item) => item.path === menu.url)) {
          // 一级菜单对应的路径
          routes.push({ path: menu.url, redirect: route.path })
        }

        // 2.二级菜单对应的路径
        routes.push(route)
      }
    }
  }
  return routes
}

loadLocalRoutes函数为加载项目路由

import type { RouteRecordRaw } from 'vue-router'

function loadLocalRoutes() {
  // 1.动态获取所有的路由对象, 放到数组中
  // * 路由对象都在独立的文件中
  // * 从文件中将所有路由对象先读取数组中
  const localRoutes: RouteRecordRaw[] = []

  // 1.1.读取router/main所有的ts文件
  const files: Record<string, any> = import.meta.glob(
    '../router/main/**/*.ts',
    {
      eager: true
    }
  )
  // 1.2.将加载的对象放到localRoutes
  for (const key in files) {
    const module = files[key]
    localRoutes.push(module.default)
  }

  return localRoutes
}