动态添加的路由 Vue3动态添加路由及生成菜单

本文介绍了在Vue3项目中遇到的动态路由不生效的问题,重点讲解了Router4.x版本中`router.addRoutes`被移除,改用`router.addRoute`的调整。通过后台返回的树形结构数据,展示了如何动态生成路由并封装路由数据。同时,给出了动态生成路由的方法及其调用过程,帮助读者理解Vue3中动态路由的配置和处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文为搬运学习,原文地址:https://blog.youkuaiyun.com/weixin_42510962/article/details/112618116?utm_term=vue3%E5%8A%A8%E6%80%81%E6%B7%BB%E5%8A%A0%E8%B7%AF%E7%94%B1&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-0-112618116&spm=3001.4430

最近在尝试用Vue3开发个管理平台项目,一切都是从头开始,基本框架搭建,熟悉Vue3写法,编写登录页,编写路由守卫,上面功能已基本完成,开始编写首页布局,用Vue3就必须用Router4.x版本,所以之前的代码迁移过来之后发现,动态路由不生效,查了很多资料,最后发现,Router4中,去掉了 router.addRoutes ,只能使用 addRoute 
6df9a0b0593190d5f63d9674c5ff2257.png

 所以之前的写法就要相应的调整,之前是可以动态添加更多的路由规则,参数必须是一个符合 routes 选项要求的数组。

router.addRoutes(routes: Array<RouteConfig>);

现在是只能添加一个

router.addRoute("名称", {
  path: `/index`,
  name: '首页',
  component: () => import(`@/index.vue`)
});

接下来就详细说明

1 路由数据封装

前台把路由写在代码里,这种方式只适用部分情况,所以大部分情况是路由后台提供,比如返回格式如下:

{
    "code": 0,
    "msg": "success",
    "data": [{
        "id": 1000,
        "parentId": -1,
        "icon": "iconquanxian",
        "name": "组织架构",
        "path": "/system",
        "component": "Layout",
        "redirect": null,
        "type": "0",
        "children": [{
            "id": 1100,
            "parentId": 1000,
            "children": [],
            "icon": "iconyonghuguanli",
            "name": "用户管理",
            "path": "/user",
            "component": "views/system/user/index",
            "redirect": null,
            "type": "0",
        }],

    }, {
        "id": 2000,
        "parentId": -1,
        "icon": "iconquanxian",
        "name": "权限管理",
        "path": "/organization",
        "component": "Layout",
        "redirect": null,
        "type": "0",
        "children": [{
            "id": 2100,
            "parentId": 2000,
            "children": [],
            "icon": "iconyonghuguanli",
            "name": "菜单管理",
            "path": "/menu",
            "component": "views/system/user/index",
            "redirect": null,
            "type": "0",
        }],

    }]
}

这种是后台树型结构返回,前台不需要进行二次处理可以直接显示成菜单,

<a-menutheme="dark"mode="inline"
>
  <a-sub-menu v-for="subitem in menuData.menu" :key="subitem.path">
    <template #title>
      <Icon-font :type="subitem.icon" />
      <span>{{ subitem.name }}span>
    template>
    <a-menu-item v-for="item in subitem.children" :key="item.path">{{
      item.name
    }}a-menu-item>
  a-sub-menu>
a-menu>

但是路由需要重新封装,先说说用到的字段,path-路由地址、component这个现在有两种,一种是Layout代表父菜单,另一种views开头的是组件地址。那么我们就可以开始动态生成路由了,写法和Vue2项目有所不同,首先定义一个方法,

const routerPackag = routers => {
  routers.filter(itemRouter => {
    if (itemRouter.component != "Layout") {
      router.addRoute("BasicLayout", {
        path: `${itemRouter.path}`,
        name: itemRouter.name,
        component: () => import(`@/${itemRouter.component}`)
      });
    }
    // 是否存在子集
    if (itemRouter.children && itemRouter.children.length) {
      routerPackag(itemRouter.children);
    }
    return true;
  });
};

 

2 调用

上面这个方式是动态生成路由,接下来就是调用这个方法。

getBasisMenu().then(res => {
  if (res.code == 0) {
    routerPackag(res.data);
  }
});

3 效果

动态路由实现了,但是现在还有部分问题未解决

4478a8df9a8eeaf2d3b331a005870079.gif

 

<think>好的,用户的问题是关于在Vue3中如何动态添加路由生成菜单的示例教程。我需要结合用户提供的三个引用内容,整理出一个清晰的步骤说明,并给出代码示例。同时,根据用户提供的系统级指令,我需要确保回答结构正确,包括正确使用LaTeX格式,生成相关问题,并在引用处添加标识。 首先,我需要回忆Vue3动态路由的基本概念。动态路由通常是在用户登录后根据权限从后端获取路由数据,然后通过addRoute方法添加路由器实例中。同时,菜单生成需要遍历路由配置中的meta字段,提取标题、图标等信息。 接下来,查看用户提供的引用内容: 引用1提到需要定义基础路由表,比如登录页404页面,提前添加到router中。登录后通过addRoute方法添加从服务器获取的路由,并利用meta字段生成菜单。这里的关键点是基础路由动态路由的分离,以及meta字段的作用。 引用2给出了一个处理路由组件的方法routerPackag,其中处理了Layout组件路由懒加载。需要将后端返回的平级路由结构转换为树形结构,以便生成菜单。代码中使用了递归处理子路由,并动态导入组件。 引用3提到在登录后存储路由数据到localStorage,解决刷新丢失路由的问题。需要将后端返回的数据传给初始化路由的方法,并持久化存储。 现在,我需要将这些信息整合成一个步骤化的教程: 1. 创建基础路由:包含无需权限的路由,如登录页、404等。 2. 登录后获取动态路由数据:从后端API获取用户权限对应的路由列表。 3. 处理路由数据:将后端返回的平级结构转换为树形结构,处理组件路径,使用懒加载。 4. 动态添加路由:使用router.addRoute()将处理后的路由添加路由器实例。 5. 生成菜单:遍历路由的meta信息,生成菜单项,可能需要递归处理嵌套路由。 6. 持久化存储:将路由数据保存到localStorage,防止刷新后丢失。 7. 处理页面刷新:在应用初始化时检查存储的路由数据,重新添加动态路由。 在代码示例部分,需要展示基础路由的定义,处理动态路由的函数,以及菜单生成的组件。同时,注意Vue3的语法,比如使用useRouter钩子,组合式API等。 需要确保LaTeX格式正确,例如变量或代码关键字使用$...$,但可能在这个问题中数学公式较少,不过如果有提及算法或数学相关内容,需注意格式。例如,提到时间复杂度时可能需要使用$O(n \log n)$。 生成的相关问题需要围绕动态路由的实现细节、菜单生成优化、权限控制等。 最后,检查引用标识是否正确添加,每个步骤末尾引用对应的来源。例如,处理路由数据的方法引用自[^2],存储到localStorage引用自[^3]等。 现在需要将这些思考整理成结构化的回答,分步骤说明,并附上代码示例。确保语言简洁,符合中文表达,同时遵循用户的格式要求。</think>### Vue3动态添加路由生成菜单的步骤示例 #### 1. 定义基础路由表 ```javascript // router/index.js import { createRouter, createWebHistory } from &#39;vue-router&#39; const staticRoutes = [ { path: &#39;/login&#39;, component: () => import(&#39;@/views/LoginView.vue&#39;), meta: { hidden: true } }, { path: &#39;/404&#39;, component: () => import(&#39;@/views/404.vue&#39;), meta: { hidden: true } } ] ``` 定义无需权限即可访问的基础路由,包含登录页404页面[^1]。 #### 2. 登录后获取动态路由 ```javascript // LoginView.vue const handleLogin = async () => { const res = await api.getRoutes() const dynamicRoutes = processRoutes(res.data) dynamicRoutes.forEach(route => router.addRoute(route)) localStorage.setItem(&#39;dynamicRoutes&#39;, JSON.stringify(res.data)) } ``` 登录成功后获取后端返回的路由数据,处理后添加路由器实例[^3]。 #### 3. 路由数据处理函数 ```javascript const processRoutes = (routes) => { return routes.map(route => { if (route.component === &#39;Layout&#39;) { route.component = () => import(&#39;@/layout/index.vue&#39;) } else { route.component = () => import(`@/views/${route.component}.vue`) } if (route.children) { route.children = processRoutes(route.children) } return route }) } ``` 处理组件路径转换路由懒加载,递归处理子路由[^2]。 #### 4. 菜单生成组件示例 ```vue <!-- Sidebar.vue --> <template> <div v-for="route in filteredRoutes"> <el-menu-item v-if="!route.children" :index="route.path"> <template #title>{{ route.meta.title }}</template> </el-menu-item> <el-sub-menu v-else :index="route.path"> <template #title>{{ route.meta.title }}</template> <sidebar-item :routes="route.children"/> </el-sub-menu> </div> </template> <script setup> const router = useRouter() const filteredRoutes = router.options.routes.filter( route => !route.meta?.hidden ) </script> ``` 根据路由的meta信息过滤生成菜单项,支持嵌套路由[^1][^2]。 #### 5. 初始化路由恢复 ```javascript // main.js const initRoutes = () => { const storedRoutes = localStorage.getItem(&#39;dynamicRoutes&#39;) if (storedRoutes) { const routes = processRoutes(JSON.parse(storedRoutes)) routes.forEach(route => router.addRoute(route)) } } initRoutes() ``` 解决页面刷新后路由丢失问题,初始化时恢复存储的路由配置。 ```mermaid graph TD A[用户登录] --> B[获取动态路由数据] B --> C[数据持久化存储] C --> D[转换路由结构] D --> E[动态添加路由] E --> F[生成菜单] F --> G[路由跳转] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值