【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…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
