Vue3 中如何根据路由动态生成侧边菜单

server/2025/3/12 12:56:09/

在 Vue3 的项目开发,尤其是后台管理系统这类复杂应用场景中,侧边菜单扮演着举足轻重的角色,它是用户快速导航至各个功能模块的得力助手。而根据路由动态生成侧边菜单,则为系统的灵活性和可扩展性增添了强大动力。接下来,我们将深入探讨如何在 Vue3 中实现这一关键功能。

gitCode代码地址:https://gitcode.com/Jiaberrr/vue3-pc-template/overview,

gitee代码地址:https://gitee.com/zunyi-gabe/vue3-pc-template (如果需要简单版(除了框架啥也没有)请切到master分支)

演示地址1:https://vue3-pc-template.vercel.app/login演示地址2:https://env-00jxt0stsnl3-static.normal.cloudstatic.cn/index.html

一、准备工作

首先,确保你的 Vue3 项目已经集成了 Vue Router 和合适的 UI 组件库(如 Element Plus,这里以其为例进行讲解,原理相通)。Vue Router 负责管理路由信息,而 UI 组件库则提供了美观且功能丰富的菜单组件供我们使用。

二、路由配置基础

  1. 在项目的路由模块(通常是 router/index.js 之类的文件)中,精心定义好各个路由路径及其对应的组件。例如:
javascript">import { createRouter, createWebHistory } from 'vue-router';import Home from '@/views/Home.vue';import About from '@/views/About.vue';import UserManage from '@/views/UserManage.vue';const routes = [{path: '/',name: 'Home',component: Home,meta: {breadcrumbName: '首页',icon: 'HomeFilled' // 假设 Element Plus 的图标名称,实际依库而定}},{path: '/about',name: 'About',component: About,meta: {breadcrumbName: '关于我们',icon: 'InfoFilled'}},{path: '/user-manage',name: 'UserManage',component: UserManage,meta: {breadcrumbName: '用户管理',icon: 'UserFilled'},children: [{path: 'list',name: 'UserList',component: () => import('@/views/UserList.vue'),meta: {breadcrumbName: '用户列表'}},{path: 'add',name: 'UserAdd',component: () => import('@/views/UserAdd.vue'),meta: {breadcrumbName: '添加用户'}}]}];const router = createRouter({history: createWebHistory(),routes});export default router;

这里,每个路由对象都有 meta 字段,用于存储菜单显示相关的额外信息,如面包屑名称和图标名称,同时部分路由设置了子路由,构建出层级结构,为侧边菜单的多级展示奠定基础。

三、组件搭建

  1. 创建侧边菜单组件(例如 SidebarMenu.vue):
javascript"><template><div class="logo-container flex-center"><img class="logo-icon" src="/img/logo.png" /><text v-if="!isCollapse">后台管理平台</text></div><el-menu:default-active="$route.path"class="el-menu-vertical-demo"routerunique-opened:collapse="isCollapse"@select="changeMenu"><el-menu-item index="/dashboard"><el-icon><Menu /></el-icon><template #title>首页</template></el-menu-item><el-sub-menu v-for="item in routerList" :index="item.path" :key="item.name"><template #title><el-icon><component :is="item.meta.icon" /></el-icon><span v-show="!isCollapse">{{ item.meta.breadcrumbName }}</span></template><el-menu-itemv-for="ite in item.children":index="item.path+ '/'+ ite.path":key="ite.name">{{ ite.meta.breadcrumbName }}</el-menu-item></el-sub-menu></el-menu>
</template><script setup>
import router from "@/router";
import { useAuthRouterStore } from "@/stores/authRouter.js";
import { useTagStore } from "@/stores/tagList.js";
const tagStore = useTagStore();
const routerOptions = router.getRoutes()const authRouterStore = useAuthRouterStore();
const props = defineProps(["isCollapse"]);
const routerList = authRouterStore.routerList;
const changeMenu = (menu) => {let obj = routerOptions.find(val => val.path == menu)tagStore.addTagList({name:obj.path,breadcrumbName:obj.meta.breadcrumbName
})}
</script><style scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 180;
}
.logo-container {width: 100%;height: 60px;overflow: hidden;
}
.logo-icon {height: 60px;scale: 1.4;
}
</style>

在模板部分:

 1、头部 logo 展示

  • 通过<div class="logo-container flex-center">包裹,实现了 logo 图标和平台名称的水平居中布局。当侧边栏处于展开状态(!isCollapse)时,显示“后台管理平台”文字,logo 图标通过<img class="logo-icon" src="/img/logo.png" />引入,并且设置了一定的样式,如高度为 60px,缩放比例为 1.4。

2、 菜单主体构建

  • 使用了 Element UI 的 <el-menu> 组件来构建侧边菜单。
  • :default-active="$route.path":将当前激活菜单与当前路由路径绑定,确保用户在页面跳转时,对应的菜单能正确高亮显示。
  • router 属性开启了路由模式,使得点击菜单能够自动触发路由跳转。
  • unique-opened 保证了同一时间只有一个子菜单处于展开状态,提升了菜单的交互体验。
  • :collapse="isCollapse":用于控制菜单的折叠状态,根据传入的 isCollapse 属性值来决定菜单是否折叠显示。
  • @select="changeMenu":绑定了菜单选择事件,当用户点击菜单时,会触发 changeMenu 方法,后续我们再详细讲解这个方法的作用。
  • 菜单分为两级结构:

          一级菜单:<el-menu-item index="/dashboard"> 代表首页菜单,有对应的图标<el-icon><Menu /></el-icon>和标题<template #title>首页</template>。

         二级菜单:通过 v-for 循环遍历 routerList 数组来生成。每个二级菜单组由 <el-sub-menu> 包裹,标题部分同样有图标和名称显示,子菜单项通过内层的 v-for 循环 item.children 生成,每个子菜单项的 index 由父级路径和自身路径拼接而成,确保路由的准确性,并且展示对应的 breadcrumbName 作为菜单名称。

在脚本部分:

1、 模块引入

  • 引入了项目的路由实例 router,这是 Vue Router 在项目中的核心模块,用于管理路由相关操作。
  • 引入了两个自定义的 Vuex 存储模块:useAuthRouterStore 和 useTagStore,分别用于管理认证相关的路由信息和标签列表信息。实例化 tagStore 和 authRouterStore 以便后续使用。

2、 组件属性接收

  • 通过 defineProps(["isCollapse"]) 接收父组件传入的 isCollapse 属性,用于控制菜单的折叠状态,与模板中的 :collapse="isCollapse" 相对应。

3、 数据获取与方法定义

  • routerList = authRouterStore.routerList:从 authRouterStore 中获取路由列表数据,这个数据应该是经过权限过滤等处理后的动态路由列表,用于在模板中生成侧边菜单。
  • changeMenu 方法:当菜单被点击时触发。它首先在 routerOptions(通过 router.getRoutes() 获取的所有路由配置信息)中查找与当前点击菜单 menu 对应的路由对象 obj。然后,调用 tagStore.addTagList 方法,向标签列表存储中添加一个新的标签对象,包含当前点击菜单对应的路由路径 name:obj.path 和面包屑名称 breadcrumbName:obj.meta.breadcrumbName,这一步可能是用于记录用户的操作历史或者构建面包屑导航等功能。

四、优化与拓展

1、 权限控制:结合后端返回的用户权限信息,在 filteredRoutes 计算属性中进一步筛选,确保用户只能看到有权访问的菜单。例如,可以在路由的 meta 字段添加权限标识,然后根据用户的权限列表进行比对过滤。

2、 动态加载菜单:对于大型项目,一次性加载所有菜单可能影响初始加载性能。可以利用 Vue 的异步组件特性,在用户点击展开二级菜单或者进入特定模块时,再动态加载子菜单对应的组件,优化资源利用。

3、 样式定制:根据项目的设计风格,深入定制侧边菜单的样式,如颜色、字体、动画效果等,提升用户视觉体验。

通过以上步骤,我们在 Vue3 中成功构建了一个根据路由动态生成的侧边菜单系统,并且为后续的功能拓展和优化铺就了坚实道路,助力打造高效、易用的 Vue3 应用。


http://www.ppmy.cn/server/158145.html

相关文章

IOS HTTPS代理抓包工具使用教程

打开抓包软件 在设备列表中选择要抓包的 设备&#xff0c;然后选择功能区域中的 HTTPS代理抓包。根据弹出的提示按照配置文件和设置手机代理。如果是本机则会自动配置&#xff0c;只需要按照提醒操作即可。 iOS 抓包准备 通过 USB 将 iOS 设备连接到电脑&#xff0c;设备需解…

【从0-1实现一个前端脚手架】

目录 介绍为什么需要脚手架&#xff1f;一个脚手架应该具备哪些功能&#xff1f; 脚手架实现初始化项目相关依赖实现脚手架 发布 介绍 为什么需要脚手架&#xff1f; 脚手架本质就是一个工具&#xff0c;作用是能够让使用者专注于写代码&#xff0c;它可以让我们只用一个命令…

FPGA的 基本结构(Xilinx 公司Virtex-II 系列FPGA )

以Xilinx 公司Virtex-II 系列FPGA 为例&#xff0c;其基本结构由下图所示。它是主要由两大部分组成&#xff1a;可编程输入/输出&#xff08;Programmable I/Os&#xff09;部分和内部可配置&#xff08;Configurable Logic&#xff09;部分。 可编程输入/输出&#xff08;I/Os…

【C语言】_函数指针变量

关于指针变量&#xff0c;本专栏相关文章链接如下&#xff1a; 【C语言】_指针变量_c语言指针变量-CSDN博客https://blog.csdn.net/m0_63299495/article/details/144883068【C语言】_字符数组与常量字符串-CSDN博客https://blog.csdn.net/m0_63299495/article/details/1450167…

windows C#-运行时泛型

C 模板和 C# 泛型之间的区别 C# 泛型和 C 模板均是支持参数化类型的语言功能。 但是&#xff0c;两者之间存在很多不同。 在语法层次&#xff0c;C# 泛型是参数化类型的一个更简单的方法&#xff0c;而不具有 C 模板的复杂性。 此外&#xff0c;C# 不试图提供 C 模板所具有的所…

超燃预告!Origin百图绘制系列即将登场

Hello&#xff0c;大家好 这里是练习时长两年半的菜狗~ 持续更新各种竞赛&#xff0c;科研&#xff0c;保研&#xff0c;学习干货ing 回想刚开始打比赛那会&#xff0c;啥都不懂&#xff0c;就从用 Excel 画图起步&#xff0c;绘制的图形实在太难看。后来运用 Matlab&#xf…

初学stm32 --- DAC输出三角波和正弦波

输出三角波实验简要&#xff1a; 1&#xff0c;功能描述 通过DAC1通道1(PA4)输出三角波&#xff0c;然后通过DS100示波器查看波形 2&#xff0c;关闭通道1触发(即自动) TEN1位置0 3&#xff0c;关闭输出缓冲 BOFF1位置1 4&#xff0c;使用12位右对齐模式 将数字量写入DAC_…

最近在盘gitlab.0.先review了一下docker

# 正文 本猿所在产品的代码是保存到了一个本地gitlab实例上&#xff0c;实例是别的同事搭建的。最近又又又想了解一下&#xff0c;而且已经盘了一些了&#xff0c;所以写写记录一下。因为这个事儿没太多的进度压力&#xff0c;索性写到哪儿算哪儿&#xff0c;只要是新了解到的…