vue3 + vite 实现一个动态路由加载功能

news2024/11/29 0:38:55

假设后端返回的格式是这样子

{
  "menu": [
    {
      "path": "/admin",
      "name": "adminLayout",
      "redirect": "/admin/index",
      "componentPath": "/layout/admin/index.vue",
      "children": [
        {
          "path": "index",
          "name": "Index",
          "meta": {
            "title": "首页",
            "keepAlive": true,
            "requireAuth": true
          },
          "componentPath": "/views/index/index.vue"
        },
        {
          "path": "logic-flow",
          "name": "LogicFlow",
          "meta": {
            "title": "可视化拖拽",
            "keepAlive": true,
            "requireAuth": true
          },
          "componentPath": "/views/logic-flow/index.vue"
        },
        {
          "path": "custom-form",
          "name": "CustomForm",
          "meta": {
            "title": "自定义表单",
            "keepAlive": true,
            "requireAuth": true
          },
          "componentPath": "/views/custom-form/index.vue"
        },
        {
          "path": "big-screen",
          "name": "BigScreen",
          "meta": {
            "title": "可视化大屏",
            "keepAlive": true,
            "requireAuth": true
          },
          "componentPath": "/views/big-screen/index.vue"
        },
        {
          "path": "d3",
          "name": "D3",
          "meta": {
            "title": "D3",
            "keepAlive": true,
            "requireAuth": true
          },
          "componentPath": "/views/d3/index.vue"
        },
        {
          "path": "konva",
          "name": "Konva",
          "meta": {
            "title": "Konva",
            "keepAlive": true,
            "requireAuth": true
          },
          "componentPath": "/views/konva/index.vue"
        },
        {
          "path": "/function",
          "name": "Function",
          "redirect": "/function/index",
          "children": [
            {
              "path": "large-file-upload",
              "name": "LargeFileUpload",
              "meta": {
                "title": "LargeFileUpload",
                "keepAlive": true,
                "requireAuth": true
              },
              "componentPath": "/views/function/large-file-upload/index.vue"
            },
            {
              "path": "virtual-list",
              "name": "VirtualList",
              "meta": {
                "title": "VirtualList",
                "keepAlive": true,
                "requireAuth": true
              },
              "componentPath": "/views/function/virtual-list/index.vue"
            }
          ]
        }
      ]
    },
    {
      "path": "/data-chart",
      "name": "DataChart",
      "meta": {},
      "componentPath": "/views/big-screen/data-chart.vue"
    }
  ]
}

在vite里主要使用到的方法是import.meta.glob,它能通过我们提供的路径动态引入相关的组件,如果我们传入了../views/**/**.vue,它返回的相关格式是这样子,这样的话就可以用过路径获取相关异步导入组件的函数了

完整代码如下(permission.ts):

import router from './index'
import { RouteRecordRaw } from 'vue-router'
import { useUserStore } from '@/store/modules/user'

const viewsModules = import.meta.glob('../views/**/**.vue')
const layoutModules = import.meta.glob('../layout/*/*.vue')

// 这个方法主要就是将componentPath转成异步引入函数component
const menuToRoutes = (menus: RouteRecordRaw[]) => {
  if (!menus || !menus.length) {
    return []
  }
  const routes: RouteRecordRaw[] = []
  menus.forEach((item: any) => {
    const meta = Object.assign({}, item.meta)
    let component
    if (item.componentPath) {
      // 如果找不到就给个404的组件
      component =
        viewsModules[`..${item.componentPath}`] ||
        layoutModules[`..${item.componentPath}`] ||
        viewsModules['../views/404/index.vue']
    }
    routes.push({
      meta,
      name: item.path,
      path: item.path,
      component: component,
      redirect: item.redirect,
      children: menuToRoutes(item.children),
    })
  })
  return routes
}

export const setupPermission = () => {
  router.beforeEach((to, from, next) => {
    const userStore = useUserStore()
    if (!userStore.menu.length) {
      // 获取路由
      // userStore.menu就是json里的menu字段
      userStore
        .setMenu()
        .then(() => {
          // 动态路由注册
          router.addRoute({
            path: '/',
            redirect: '/admin',
            children: menuToRoutes(userStore.menu),
          })
          next({ ...to, replace: true })
        })
        .catch(() => {
          next()
        })
    } else {
      next()
    }
  })
}

最后在main.js里调用一下setupPermission方法就行~

PS: 如果退出登录需要清除动态路由的话,因为现在vue-router没有提供可以直接清空的方法,所以可以考虑返回登录页后刷新一下界面来解决~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1530023.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Could not locate zlibwapi.dll. Please make sure it is in your library path!

背景 运行PaddleOCR时,用的CUDA11.6配的是cuDNN8.4。但是运行后却报错如下。 解决手段 去网上找到这两个文件,现在英伟达好像不能下载了,但是可以去网盘下载。然后把dll文件放入CUDA11.6文件下的bin目录,而lib文件放入CUDA11.6文…

基于YOLOv8的航空遥感飞机小目标检测

💡💡💡本文摘要:基于YOLOv8的航空遥感飞机小目标检测,阐述了整个数据制作和训练可视化过程 1.YOLOv8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先…

js检测数据类型方式(typeof instanceof Object.prototype.toString.call())

typeof 使用 typeof 检测数据类型,首先返回的都是一个字符串,其次字符串中包含了对应的数据类型; 缺点: typeof null "object"不能具体细分是数组、正则还是对象中其他值,使用 typeof 检测数据类型对于对…

微服务day03 -- Docker

1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势,但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中,依赖的组件非常多,不同组件之间部署时往往会产生一些冲突。 在数百上千台服务中重复部署,环境不一定一致…

59、服务攻防——中间件安全CVE复现IISApacheTomcatNginx

文章目录 中间件——IIS漏洞中间件——Nginx漏洞中间件——Apache中间件——Tomcat 中间件:IIS、Apache、Nginx、Tomcat、Docker、Weblogic、JBoss、WebSphere、Jenkinsphp框架:Laravel、Thinkphppythonl框架:Flaskjs框架:jQueryj…

vue+elementui中table实现单选行功能

el-table插件可以选择行,但是只能多选,而项目中有单选的需求。 效果如下图所示,点击行或者点击复选框都可以选中行(高亮,复选框选中),并且每次只选中当前行,之前选中的行清空。点击标…

Panasonic松下PLC如何数据采集?如何实现快速接入IIOT云平台?

在工业自动化领域,数据采集与远程控制是提升生产效率、优化资源配置的关键环节。对于使用Panasonic松下PLC的用户来说,如何实现高效、稳定的数据采集,并快速接入IIOT云平台,是摆在他们面前的重要课题。HiWoo Box工业物联网关以其强…

TikTok云手机是什么原理?

随着社交媒体的快速发展和普及,TikTok已成为全球最受欢迎的短视频平台之一,吸引了数以亿计的用户。在TikTok上,许多用户和内容创作者都希望能够更灵活地管理和运营多个账号,这就需要借助云手机技术。那么,TikTok云手机…

通过el-table实现表格穿梭框

element-ui自带的el-transfer界面比较简单&#xff0c;通过el-table实现表格形式的穿梭框功能 首先是效果图 示例图样式比较简单&#xff0c;但是el-table是完全通过div包裹的&#xff0c;所以里面可以自己添加更多的其他组件实现想要的功能 <div style"display: flex…

微信小程序 ---- 慕尚花坊 结算支付

结算支付 01. 配置分包并跳转到结算页面 思路分析&#xff1a; 随着项目功能的增加&#xff0c;项目体积也随着增大&#xff0c;从而影响小程序的加载速度&#xff0c;影响用户的体验。 因此我们需要将 结算支付 功能配置成一个分包&#xff0c; 当用户在访问设置页面时&a…

鸿蒙Harmony应用开发—ArkTS声明式开发(画布组件:Path2D)

路径对象&#xff0c;支持通过对象的接口进行路径的描述&#xff0c;并通过Canvas的stroke接口或者fill接口进行绘制。 说明&#xff1a; 从 API Version 8 开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 addPath addPath(path: path2D,…

【Web技术应用基础】HTML(1)——简单界面

题目1&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Hello world</title></head> <body bgcolor"F6F3D6"><!--用HTML语言向世界打声招呼吧&#xff01;--><h1 align&…

windows系统下python进程管理系统

两年来&#xff0c;我们项目的爬虫代码大部分都是放在公司的windows机器上运行的&#xff0c;原因是服务器太贵&#xff0c;没有那么多资源&#xff0c;而windows主机却有很多用不上。为了合理利用公司资源&#xff0c;降低数据采集成本&#xff0c;我在所以任务机器上使用anac…

如何解决node-sass下载用的还是过期的淘宝源?

下载node-sass发现报错过期的证书 把npm的淘宝源换成最新的https://registry.npmmirror.com后发现还是指向了以前的淘宝源&#xff0c;看到一位博主说&#xff0c;单改npm源不够还要改下载node-sass的源&#xff0c;再次搜索另外一位博主提供了命令npm config ls可以使用它来查…

Http 超文本传输协议基本概念学习摘录

目录 HTTP协议 超文本传输协议 HyperText超文本 HTML超文本标记语言 HTTP协议原理 请求发送 服务器处理 响应发送 连接关闭或保持 HTTP协议版本 HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/3 HTTP请求方法 GET POST PUT DELETE HEAD OPTIONS HTTP请求头字…

模拟算法总述

模拟 1.模拟算法介绍 模拟算法通过模拟实际情况来解决问题&#xff0c;一般容易理解但是实现起来比较复杂&#xff0c;有很多需要注意的细节&#xff0c;或者是一些所谓很”麻烦”的东西。 模拟题一般不涉及太难的算法&#xff0c;一般就是由较多的简单但是不好处理的部分组成…

xinference - 大模型分布式推理框架

文章目录 关于 xinference使用1、启动 xinference设置其他参数 2、加载模型3、模型交互 其它报错处理 - transformer.wte.weight 关于 xinference Xorbits Inference&#xff08;Xinference&#xff09;是一个性能强大且功能全面的分布式推理框架。 可用于大语言模型&#xff…

【重温设计模式】状态模式及其Java示例

状态模式的基本概念 在编程世界的大海中&#xff0c;各种设计模式就如同灯塔&#xff0c;为我们的代码编写指明方向。其中&#xff0c;状态模式是一种行为设计模式&#xff0c;它让你能在一个对象的内部状态改变时改变其行为&#xff0c;使得对象看起来就像改变了其类一样。这…

Flink中任务(Tasks)和任务槽(Task Slots)详解

Flink中任务&#xff08;Tasks&#xff09;和任务槽&#xff08;Task Slots&#xff09;详解 任务槽&#xff08;Task Slots&#xff09; Flink中每一个worker(也就是TaskManager)都是一个JVM进程&#xff0c;它可以启动多个独立的线程&#xff0c;来并行执行多个子任务&#…

从零开始搭建游戏服务器 第四节 MongoDB引入并实现注册登录

这里写目录标题 前言正文添加依赖安装MongoDB添加MongoDB相关配置创建MongoContext类尝试初始化DB连接实现注册功能测试注册功能实现登录逻辑测试登录流程 结语下节预告 前言 游戏服务器中, 很重要的一点就是如何保存玩家的游戏数据. 当一个服务端架构趋于稳定且功能全面, 开发…