当前位置: 首页 > article >正文

vue3 vite 动态加载路由遇到的问题

记录一下动态加载路由遇到的问题

正常使用import引入静态路由是没问题的

component: () => import('@/components/ExampleComponent.vue')

动态引入的时候写成import就不行了
由于后端给的路由格式比较反人类…我这边先递归把获取到的数据格式做了一个整合.

const processedData = res.data.map((item) => {
  // 递归函数来处理子路由
  const processChildren = (children) =>
    (children || []).map((childItem) => ({
      path: childItem.path,
      name: childItem.name,
      component: childItem.permsLevel == 1 ? 'Layout' : childItem.path, // 如果菜单是一级
      meta: {
        id: childItem.id,
        icon: childItem.icon || undefined,
        title: childItem.title,
      },
      // 递归处理更深层次的子路由
      ...(childItem.menuTwoList || childItem.menuThreeList
        ? {
            children: processChildren(childItem.menuTwoList || childItem.menuThreeList),
          }
        : {}),
    }))

  // 创建一个新对象以避免直接修改原始数据
  const route = {
    path: item.path,
    name: item.name,
    component: item.permsLevel == 1 ? 'Layout' : item.path,
    meta: {
      id: item.id,
      icon: item.icon || undefined,
      title: item.title,
    },
    // 递归处理子路由
    ...(item.menuTwoList || item.menuThreeList
      ? {
          children: processChildren(item.menuTwoList || item.menuThreeList),
        }
      : {}),
  }
  // 这里要注意的就是如果子路由没有children一定要删除,不然点击显示不出来Layout
  if (route.children.length == 0) {
    delete route.children
  }
  return route
})
// 我这边是因为后端给的children可能叫menuTwoList 或者menuThreeList才进行这样的处理
// 如果大家只是都叫children就不需要这样了

现在我们拿到的数据就是正常的路由格式了,但是还差一步动态引入路由

在permission.ts里面找到router.beforeEach,就是咱们的路由守卫了

if (to.path === '/login') {
 // 如果已登录,请重定向到主页
  next({ path: '/' })
} else {
  try {
    const PermissionStore = usePermissionStore()
    // 路由添加进去了没有及时更新 需要重新进去一次拦截
    if (!PermissionStore.routes.length) {
      // 获取权限列表进行接口访问 因为这里页面要切换权限
      const accessRoutes = await PermissionStore.generateRoutes(UserStore.roles)
      hasRoles = false
      // 在这里进行动态路由的添加
      await processRoutes(accessRoutes)
      next({ ...to, replace: true }) // // 这里相当于push到一个页面 不在进入路由拦截
    } else {
      next() // // 如果不传参数就会重新执行路由拦截,重新进到这里
    }
  } catch (error) {
    next(`/login?redirect=${to.path}`)
  }
}

processRoutes和resolveComponent的方法我就贴在这边大家参考一下

const modules = import.meta.glob('/src/views/**/*.vue')
const layout = import.meta.glob('/src/layout/**/*.vue')
// 记录路由
const resolveComponent = (path: string, type: any) => {
  // 拿到views下面的所有文件之后,动态拼接`key`去获取value
  const importPage = type ? modules[`/src/views${path}.vue`] : layout[`/src/${path}.vue`]
  // console.log(importPage)
  if (!importPage) {
    throw new Error(`Unknown page ${path}. Is it located under Pages with a .vue extension?`)
  }
  return importPage
}
const processRoutes = async (routes) => {
  routes.forEach((item) => {
    // 检查当前路由项是否需要替换组件
    if (item.component === 'Layout') {
      item.component = resolveComponent('layout/index', null)
    } else {
      item.component = resolveComponent(item.path, 1)
    }
    // 添加当前路由到路由器
    // 如果当前路由项有子路由,则递归处理
    if (item.children && Array.isArray(item.children)) {
      processRoutes(item.children)
    }
    router.addRoute(item)
  })
}

完结
觉得写的比较全面的请给一个小星星.谢谢~


http://www.kler.cn/a/467673.html

相关文章:

  • Cursor AI 编程代码助手:设置自定义 AI 与 OpenAI API Key 获取教程
  • centos7 init.d 和system.d
  • 练习题:37
  • Zotero7(64位)更新:旧版本的卸载与文献同步问题
  • 【数据结构-堆】力扣3066. 超过阈值的最少操作数 II
  • Day 23:接口文档与 Swagger
  • 机器学习深度学习快速上手
  • 智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之11 方案再探之2 项目文件(修改稿1)
  • 什么情况会导致JVM退出?
  • 每日一学——日志管理工具(ELK Stack)
  • java基础学习(接口和抽象类的区别)
  • Gitea代码仓服务搭建
  • node.js内置模块之---http 和 https 模块
  • 在macOS上安装MySQL
  • vscode代码AI插件Continue 安装与使用
  • 七大设计原则之开闭原则
  • 嵌入式linux中数据结构详解与分析
  • k8s基础(4)—Kubernetes-Service
  • 【socketioxide和axum集成-实现websocket实时通信-Rust点滴】
  • VR线上展厅如何重塑展览展示新生态,引领科技潮流?