【Vue3项目实战】vue3项目基于el-menu封装左侧菜单栏组件
文章目录
- 概述
- 一、先看效果
- 1.1 静态效果
- 1.2 动态效果
- 二、核心思路
- 三、全量代码
- 3.1 文件目录结构
- 3.2 /sidebar/index.vue 中
- 3.3 /sidebar/sidebarItem.vue 中
- 3.4 路由表结构
- 四、代码讲解
- 五、SVG组件
- 六、系列文章友链
- 1、[配置husky、stylelint、commitlint,实现git提交前代码校验](http://t.csdn.cn/226Xn)
- 2、[配置@路径别名,实现@代替/src](http://t.csdn.cn/mMEwO)
- 3、[配置 vue-router路由跳转,并完成路由模块化](http://t.csdn.cn/4r1ht)
- 4、[配置vue-i18n中英文切换,完成国际化](http://t.csdn.cn/xyOaV)
- 5、[配置滚动条样式](http://t.csdn.cn/cUkdA)
- 6、[项目引入Element-plus,并配置按需自动导入](http://t.csdn.cn/mxdsS)
- 7、[配置页面切换,路由跳转过渡动画](http://t.csdn.cn/LEKk6)
- 8、[配置nprogress,实现路由加载进度条](http://t.csdn.cn/inFOa)
概述
做什么:封装通用左侧菜单栏组件
怎么做:使用Element-Plus组件库中的el-menu组件进行二次封装
技术栈:Vue3 + Ts + Vite,且采用 setup 语法糖写法
准备工作:请各位自行引入Element-plus组件库,本文中有用到 svg组件,svg组件封装教程请看第五点
一、先看效果
1.1 静态效果

1.2 动态效果

二、核心思路
查看
Element-plus组件库中的el-menu组件,不难发现,菜单栏大致可以分为两类,一类是有子菜单的,一类是无子菜单的。
所以我们将对这两类进行分情况设计,再结合递归,即可完成根据路由列表,动态渲染菜单栏

三、全量代码
3.1 文件目录结构

3.2 /sidebar/index.vue 中
<script lang="ts" setup>
// sidebarItem 项组件
import SideBarItem from './sidebarItem.vue';
import { useRouter } from 'vue-router';
// 拿到路由列表,过滤我们不想要的
const router = useRouter();
const routerList = router.getRoutes().filter((v) => v.meta && v.meta.isShow);
</script>
<template><div class="sidebar"><!-- 项目名称及logo --><div class="sidebar-logo flex-center"><svg-icon icon-class="logo" /><span>VitalityAdmin</span></div><!-- 导航菜单 --><el-menuactive-text-color="#fff"background-color="#001529":default-active="$route.path"text-color="#999":unique-opened="true"router><!-- 引入子组件 --><SideBarItem :routerList="routerList" /></el-menu><!-- active-text-color:当前菜单项被选中时,字体的颜色 --><!-- background-color:这个menu菜单的背景色 --><!-- default-active: 当前激活菜单的 index --><!-- text-color:菜单项字体颜色 --><!-- unique-opened:unique-opened 是否只保持一个子菜单的展开 --><!-- router:是否使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转 --></div>
</template>
<style lang="scss" scoped>
.sidebar {height: 100%;.sidebar-logo {height: 48px;background-color: #002140;color: #fff;font-weight: 700;line-height: 48px;text-align: center;font-size: 20px;}.el-menu {height: calc(100% - 48px);border-right: 0;overflow: auto;}
}
</style>
3.3 /sidebar/sidebarItem.vue 中
<script setup lang="ts">
import { RouteRecordRaw } from 'vue-router';
// 做类型限制,解决ts类型报错
type CustomRouteRecordRaw = RouteRecordRaw & {meta: {isShow?: boolean;};
};
const props = defineProps({// 拿到父组件传递过来的路由列表进行渲染routerList: {type: Array as () => CustomRouteRecordRaw[],required: true}
});
</script>
<template><template v-for="item in props.routerList" :key="item.path"><!-- 当该菜单项有子菜单时 --><el-sub-menu :index="item.path" v-if="item.children && item.children.length > 0"><template #title v-if="item.meta.icon"><!-- 菜单项图标,我此处用的是全局封装的 svg组件 --><el-icon><svg-icon :icon-class="item.meta.icon" /></el-icon><!-- 菜单项名称,在路由中定义好 --><span>{{ item.meta.title }}</span></template><!-- 若路由中未定义菜单项icon,则仅展示名称--(我的仅一级菜单有图标) --><template #title v-else>{{ item.meta.title }}</template><!-- 递归遍历-自己调用自己(核心代码) --><sidebarItem :routerList="( item.children as CustomRouteRecordRaw[])" /></el-sub-menu><!-- 当前菜单项无子菜单 --><el-menu-item :index="item.path" v-else><!-- 与上面注释大致相同,不多做额外注释 --><template v-if="item.meta.icon"><el-icon><svg-icon :icon-class="item.meta.icon" /></el-icon><span>{{ item.meta.title }}</span></template><template v-else>{{ item.meta.title }}</template></el-menu-item></template>
</template><style scoped lang="scss">
.is-active {background: #409eff;font-weight: 700;
}.el-menu-item {&:hover {color: #fff;font-weight: 700;}
}.el-menu--collapse {.el-menu-item {justify-content: center;}
}// 下列代码是用于兼容horizontal所写,酌情删或留
.el-menu--horizontal {.el-menu-item.is-active {background-color: transparent !important;border-bottom: 2px solid #409eff !important;.el-icon,span {color: #409eff !important;}}.el-sub-menu.is-active {.el-sub-menu__title {border: 0 !important;}.el-icon,span {color: #409eff !important;}}
}
</style>
3.4 路由表结构
isShow: true, // 控制当前项是否在菜单栏中渲染出来,比如你写了 login 页面的路由,但是并不希望 login在menu菜单中渲染出来,即可设为false
title: ‘首页’, // menu菜单项的名称,没啥好说的
icon: ‘menu-home’ // menu菜单项的图标,我此处是与封装好的 svg 组件结合使用的
export default [{path: '/layout',name: 'layoutIndex',component: () => import('@/layout/index.vue'),children: [{path: '/home',name: 'homeIndex',component: () => import('@/views/home/index.vue'),meta: {isShow: true, // 控制当前项是否在菜单栏中渲染出来,比如你写了 login 页面的路由,但是并不希望 login在menu菜单中渲染出来,即可设为falsetitle: '首页', // menu菜单项的名称,没啥好说的icon: 'menu-home' // menu菜单项的图标,我此处是与封装好的 svg 组件结合使用的}},{path: '/echarts',name: 'echartIndex',// component: () => import('@/views/echarts/index.vue'),meta: {isShow: true,title: 'Echarts页',icon: 'menu-echarts'},children: [{path: '/echarts/barCharts',name: 'barCharts',component: () => import('@/views/echarts/barCharts.vue'),meta: {title: '柱状图'}},{path: '/echarts/pieCharts',name: 'pieCharts',component: () => import('@/views/echarts/pieCharts.vue'),meta: {title: '饼图'}}]},{path: '/package',name: 'packageIndex',component: () => import('@/views/package/index.vue'),meta: {isShow: true,title: '组件',icon: 'menu-package'}},{path: '/menu',name: 'menuIndex',redirect: '/menu/menu-1',meta: {isShow: true,title: '一级菜单',icon: 'menu-package'},children: [{path: '/menu/menu-1',name: 'menu-1',component: () => import('@/views/menu/menu1.vue'),meta: {title: '二级菜单-1'}},{path: '/menu/menu-2',name: 'menu-2',component: () => import('@/views/menu/menu2.vue'),meta: {title: '二级菜单-2'},children: [{path: '/menu/menu-2/children',name: 'menu3',component: () => import('@/views/menu/menu3.vue'),meta: {title: '三级菜单'}}]}]}]}
];
四、代码讲解


五、SVG组件
本文不展开讲解
svg组件的封装与使用,有需要的朋友欢迎参考下面的svg组件封装教程
svg组件封装教程:http://t.csdn.cn/uYsSJ
六、系列文章友链
本系列文章记录了
从零到一🚀 搭建Vue3+Ts+Vite项目的全过程
包括但不限于项目配置、组件封装、过渡动画等 🚚
系列文章持续更新中~~👨🏻💻,有任何问题欢迎👏评论区留言
最后,希望本文都能对你有一点🤏🏽帮助,点赞收藏不迷路🍺
1、配置husky、stylelint、commitlint,实现git提交前代码校验
2、配置@路径别名,实现@代替/src
3、配置 vue-router路由跳转,并完成路由模块化
4、配置vue-i18n中英文切换,完成国际化
5、配置滚动条样式
6、项目引入Element-plus,并配置按需自动导入
7、配置页面切换,路由跳转过渡动画
8、配置nprogress,实现路由加载进度条
相关文章:
【Vue3项目实战】vue3项目基于el-menu封装左侧菜单栏组件
文章目录 概述一、先看效果1.1 静态效果1.2 动态效果 二、核心思路三、全量代码3.1 文件目录结构3.2 /sidebar/index.vue 中3.3 /sidebar/sidebarItem.vue 中3.4 路由表结构 四、代码讲解五、SVG组件六、系列文章友链1、[配置husky、stylelint、commitlint,实现git提…...
MySQL正则表达式检索数据
目录 一、使用正则表达式进行基本字符匹配 1.使用regexp关键字 2.使用正则表达式 . 二、进行OR匹配 1.为搜索两个串之一,使用 | 2.匹配几个字符之一[] 3.匹配范围 4.匹配特殊字符 过滤数据允许使用匹配、比较、通配符操作来寻找数据,但是随…...
vite+ts+vue3 prettier.config.js 不生效问题解决
vitetsvue3 prettier.config.js 不生效问题解决 我在做项目的时候 我发现 我的vscode prettier插件 坏了 我自动格式化代码也开了 就是不给我格式化, 我已经写了prettier.config.js这个配置 也 npm i prettier 下载了就是不生效 后来我发现是因为 这个package.json 里的 “ty…...
Java源码规则引擎:jvs-rules 8月新增功能介绍
JVS-rules是JAVA语言下开发的规则引擎,是jvs企业级数字化解决方案中的重要配置化工具,核心解决业务判断的配置化,常见的使用场景:金融信贷风控判断、商品优惠折扣计算、对员工考核评分等各种变化的规则判断情景。 8月是收获的季节…...
2023年第三届工业自动化、机器人与控制工程国际会议 | IET独立出版 | EI检索
会议简介 Brief Introduction 2023年第三届工业自动化、机器人与控制工程国际会议(IARCE 2023) 会议时间:2023年10月27 -30日 召开地点:中国成都 大会官网:www.iarce.org 2023年第三届工业自动化、机器人与控制工程国际…...
14.2.2 【Linux】software, hardware RAID
磁盘阵列分为硬件与软件。所谓的硬件磁盘阵列是通过磁盘阵列卡来达成阵列的目的。磁盘阵列卡上面有一块专门的芯片在处理 RAID 的任务,因此在性能方面会比较好。在很多任务 (例如 RAID 5 的同位检查码计算) 磁盘阵列并不会重复消耗原本系统的…...
(学习笔记-进程管理)进程
进程 我们编写的代码只是一个存储在硬盘的静态文件,通过编译后会生成二进制可执行文件,当我们运行这个可执行文件后,它会被装载到内存中,接着CPU会执行程序中的每一条指令,那么这个运行中的程序就被称为进程。 现在我…...
《Linux从练气到飞升》No.07 Linux第一个小程序-进度条的实现
🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的…...
【NLP概念源和流】 04-过度到RNN(第 4/20 部分)
接上文 【NLP概念源和流】 03-基于计数的嵌入,GloVe(第 3/20 部分) 一、说明 词嵌入使许多NLP任务有了显著的改进。它对单词原理图的理解以及将不同长度的文本表示为固定向量的能力使其在许多复杂的NLP任务中非常受欢迎。大多数机器学习算法可以直接应用于分类和回归任务的…...
企业上云实施路线图
企业上云步骤主要分为规划、设计、实施、验证、运维五个阶段。https://articles.e-works.net.cn/cloud/article144684.htm...
docker系列--解决hyper-v导致docker无法启动问题
一、问题 windows docker desktop 启动报错异常,导致docker无法启动成功 我们看到问题出在hyper-v的问题上,搜索解决方法,官网常见问题如下 Overview | Docker Documentation 二、解决 Hyper-V 已安装并正常工作 在BIOS中启用虚拟化 Wind…...
socket server服务器开发常见的并发模型
两种高效的事件处理模式 服务器程序通常需要处理三类事件:I/O 事件、信号及定时事件。有两种高效的事件处理模式:Reactor和 Proactor,同步 I/O 模型通常用于实现Reactor 模式,异步 I/O 模型通常用于实现 Proactor 模式。 无论是 …...
怎么修改pdf文件中的文字?分享几种编辑方法
怎么修改pdf文件中的文字?PDF格式的文件通常具有很高的可读性和稳定性,但是如果需要修改其中的文字,就需要使用专门的PDF编辑器。本文将介绍几种PDF编辑的方法,下面就跟着我一起来看看这几款工具吧。 方法一:使用迅捷P…...
spring — Spring Security 5.7与6.0差异性对比
1. spring security Spring Security 是一个提供身份验证、授权和针对常见攻击保护的框架。 凭借对保护命令式和反应式应用程序的一流支持,它成为基于Spring的标准安全框架。 Spring Security 在最近几个版本中配置的写法都有一些变化,很多常见的方法都…...
道本科技受邀参加建筑产业互联网推动建筑产业现代化体系构建座谈会,以数字化产品为建筑行业注入新动能!
2023年7月底,道本科技作为中国建筑业协会合作伙伴,受邀参加了建筑产业互联网推动建筑产业现代化体系构建座谈会。在这次座谈会上,道本科技旗下产品“合规数”“合同智能审查”和“智合同范本库”被中国建筑(中小企业)产…...
数据结构----效率问题
数据结构----效率问题 一.衡量效率 1.衡量效率的两个维度 1.时间维度:时间复杂度:Time Complexity 时间复杂度是代码总的运行次数(粗糙) 2.空间维度:空间复杂度:Space Complexity 空间复杂度是额外申…...
【BASH】回顾与知识点梳理(五)
【BASH】回顾与知识点梳理 五 五. 数据流重导向5.1 什么是数据流重导向standard output 与 standard error output/dev/null 垃圾桶黑洞装置与特殊写法standard input : < 与 << 5.2 命令执行的判断依据: ; , &&, ||cmd ; cmd (不考虑指…...
PCL点云处理之最小二乘空间直线拟合(3D) (二百零二)
PCL点云处理之最小二乘空间直线拟合(3D) (二百零二) 一、算法简介二、实现代码三、效果展示一、算法简介 对于空间中的这样一组点:大致呈直线分布,散乱分布在直线左右, 我们可采用最小二乘方法拟合直线,更进一步地,可以通过点到直线的投影,最终得到一组严格呈直线分布…...
大数据课程G1——Hbase的概述
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解HIve的概念; ⚪ 了解HIve与数据库的区别; ⚪ 了解HIve的特点; 一、简介 1. 概述 1. HBase原本是由Yahoo!公司开发后来贡献给了…...
第三章 图论 No.2单源最短路之虚拟源点,状压最短路与最短路次短路条数
文章目录 1137. 选择最佳线路1131. 拯救大兵瑞恩1134. 最短路计数383. 观光 dp是特殊的最短路,是无环图(拓扑图)上的最短路问题 1137. 选择最佳线路 1137. 选择最佳线路 - AcWing题库 // 反向建图就行 #include <iostream> #include…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
