我一人全干!之二,vue3后台管理系统树形目录的实现。

一个完整的后台管理系统需要一个树形结构的目录,方便用户切换页面。

毒蘑菇后台管理
因为使用的是element-plus的ui库,所以首选el-menu组件,点击查看文档。
因为此组件不是树形结构的,所以需要封装成系统需要的树形结构组件。可以使用vue的递归组件。
menu.vue代码如下

<template><div class="menu-container"><el-scrollbar height="100%"><el-menu ref="ElMenuRef":collapse="false":default-active="route.path":router="false"><MenuItemv-for="item,index in dataContainer.dataList":key="item.path":dataInfo="item"></MenuItem></el-menu></el-scrollbar></div>
</template>
<script>
import {defineComponent,ref,reactive,computed,onMounted,watch,toRef,onUnmounted,
} from 'vue';
import SvgIcon from "@/components/svgIcon/index.vue";
import { useRouter,useRoute } from "vue-router";
import MenuItem from "./MenuItem.vue";export default {name: 'Menu',components: {SvgIcon,MenuItem,},props:{/** 所显示的数据列表 */dataList:{type:Array,default:()=>{return [];},},},setup(props) {const router = useRouter();const route = useRoute();const ElMenuRef = ref(null);const dataContainer = reactive({dataList:toRef(props,'dataList'),});/** * 当页面加载后设置设置当前打开的父节点,因为如果父节点可点击的话不会自动打开* */onMounted(()=>{if(!ElMenuRef.value) return;let el = ElMenuRef.value.$el;let hasActiveSubEl = el.querySelector('.el-sub-menu .is-sub-defin-active');if(!hasActiveSubEl) return;ElMenuRef.value.open(route.path);});return {dataContainer,route,ElMenuRef,};},
};
</script>
<style scoped lang="scss">
.menu-container {height: 100%;width: 100%;/** 基础目录配置 */--local-active-text-color:#ffffff;--local-active-bg-color:#5240ff96;--local-active-sub-bg-color:#3634ac57;--local-hover-color:#3634ac57;--local-font-size:15px;--local-text-color:#b6cce2;--local-box-shadow: 0 1px 4px #001247;--local-border-radius:8px;:deep(.el-menu){border:none !important;--el-menu-active-color:var(--local-active-text-color) !important;--el-menu-item-font-size:var(--local-font-size) !important;--el-menu-text-color:var(--local-text-color) !important;--el-menu-hover-bg-color:var(--local-hover-color) !important;--active-item-bg-color:var(--local-active-bg-color) !important;--el-menu-bg-color:transparent !important;--el-menu-base-level-padding:15px !important;--el-menu-level-padding:20px !important;--el-menu-icon-width:calc(15px + 0) !important; --el-menu-item-height:55px !important;--el-menu-sub-item-height:55px !important;--active-sub-bg-color:transparent !important;padding: 10px;box-sizing: border-box;.el-sub-menu__icon-arrow{margin-top: 0 !important;top:initial !important;}.el-menu{padding: 0;}.el-sub-menu{>.el-sub-menu__title{border-radius: var(--local-border-radius);}&.is-active{background-color: var(--active-sub-bg-color);>.el-sub-menu__title{background-color: var(--local-active-sub-bg-color);}}.el-sub-menu__icon-arrow{font-size: 17px !important;}&.is-sub-defin-active{>.el-sub-menu__title{background-color: var(--active-item-bg-color);// font-weight: bold;color: var(--el-menu-active-color);box-shadow: var(--local-box-shadow);}}/** 表示有已经活动的sub目录 */&:has(.is-sub-defin-active){background-color: var(--active-sub-bg-color);>.el-sub-menu__title{background-color: var(--local-active-sub-bg-color);}}}.el-menu-item{border-radius: var(--local-border-radius);&.is-active{background-color: var(--active-item-bg-color);// font-weight: bold;box-shadow: var(--local-box-shadow);}}}:deep(.el-scrollbar){.el-scrollbar__bar{.el-scrollbar__thumb{background-color: rgba(194, 194, 194, 0.51) !important;}}}
}
</style>

其中子组件MenuItem.vue代码如下

<template><div class="menu-item-container"><!-- 没有子目录的 --><el-menu-itemv-if="!dataContainer.dataInfo.childs || dataContainer.dataInfo.childs.length==0":index="dataContainer.dataInfo.path":class="{'is-active':dataContainer.dataInfo.path==route.path,}"@click="handleClick(dataContainer.dataInfo)"><div class="item-target"><SvgIconv-if="dataContainer.dataInfo.iconName":style="'width: 17px;min-width:17px;height: 17px;'":name="dataContainer.dataInfo.iconName"></SvgIcon>{{dataContainer.dataInfo.title}}<divv-if="dataContainer.dataInfo.content"class="content">{{dataContainer.dataInfo.content}}</div><divv-if="dataContainer.dataInfo.number"class="sign">{{dataContainer.dataInfo.number}}</div></div></el-menu-item><!-- 有子目录且父节点可点击 --><el-sub-menu v-else-if="dataContainer.dataInfo.path":class="{'is-sub-defin-active':route.path==dataContainer.dataInfo.path,}":index="dataContainer.dataInfo.path"><template #title><div class="item-target"@click.stop="handleClick(dataContainer.dataInfo)"><SvgIconv-if="dataContainer.dataInfo.iconName":style="'width: 17px;min-width:17px;height: 17px;'":name="dataContainer.dataInfo.iconName"></SvgIcon>{{dataContainer.dataInfo.title}}<divv-if="dataContainer.dataInfo.content"class="content">{{dataContainer.dataInfo.content}}</div><divv-if="dataContainer.dataInfo.number"class="sign">{{dataContainer.dataInfo.number}}</div></div></template><MenuItemv-for="item,index in dataContainer.dataInfo.childs":key="item.path":dataInfo="item"></MenuItem></el-sub-menu><!-- 有子目录且父节点不可点击 --><el-sub-menu v-else:index="dataContainer.dataInfo.sign"><template #title><div class="item-target"><SvgIconv-if="dataContainer.dataInfo.iconName":style="'width: 17px;min-width:17px;height: 17px;'":name="dataContainer.dataInfo.iconName"></SvgIcon>{{dataContainer.dataInfo.title}}<divv-if="dataContainer.dataInfo.content"class="content">{{dataContainer.dataInfo.content}}</div><divv-if="dataContainer.dataInfo.number"class="sign">{{dataContainer.dataInfo.number}}</div></div></template><MenuItemv-for="item,index in dataContainer.dataInfo.childs":key="item.path":dataInfo="item"></MenuItem></el-sub-menu></div>
</template>
<script>
import {defineComponent,ref,reactive,computed,onMounted,watch,toRef,onUnmounted,
} from 'vue';
import SvgIcon from "@/components/svgIcon/index.vue";
import { useRouter,useRoute } from "vue-router";export default {name: 'MenuItem',components: {SvgIcon,},props:{/** 所显示的数据列表 */dataInfo:{type:Object,default:()=>{return {};},},},setup(props) {const router = useRouter();const route = useRoute();const dataContainer = reactive({dataInfo:toRef(props,'dataInfo'),});/** 跳转相应链接 */function handleClick(params){if(!params.path) return;/** 如果是一个链接的话直接跳转 */if(params.isLink){window.open(params.path);}else{router.push(params.path);}}return {dataContainer,handleClick,route,};},
};
</script>
<style scoped lang="scss">
.menu-item-container {height: fit-content;width: 100%;:deep(.item-target){width: 100%;display: flex;flex-direction: row;align-items: center;position: relative;>*{margin-right: 10px;}>.sign{right: 0;position: absolute;width: fit-content;background-color: #ffe4e4;color: #f56c6c;border-radius: 999px;padding: 5px 10px;box-sizing: border-box;line-height: 1;font-size: 12px;margin: 0;font-weight: bold;}>.content{font-size: 12px;margin-left: 5px;opacity: 0.8;font-weight: 400 !important;}}
}
</style>

这样就可以实现一个树形结构的系统目录了。
DEMO,源码

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

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

相关文章

Vue3 Element-Plus 一站式生成动态表单:简化前端开发流程

文章目录 1. 引言2. Vue3 和 Element-Plus 简介2.1 Vue32.2 Element-Plus 3. 动态表单的需求与挑战4. Vue3 和 Element-Plus 动态表单的优势4.1 Vue3的组合式API4.2 Element-Plus的表单组件 5. 一站式生成动态表单的实现5.1 准备工作5.2 创建动态表单组件5.3 使用动态表单组件 …

2023年2月8日 Go生态洞察:Profile-Guided Optimization预览

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

易点易动设备管理系统--提升设备能耗管理效率的工具

在当今的节能环保意识日益增强的社会背景下&#xff0c;设备能耗管理成为了市场推广人员关注的焦点之一。为了帮助市场推广人员提升设备能耗管理效率&#xff0c;易点易动设备管理系统应运而生。本文将详细介绍易点易动设备管理系统的功能和优势&#xff0c;以及如何借助该系统…

2023年12月实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】

首先&#xff0c;来看下效果图 在线体验地址&#xff1a;https://geojson.hxkj.vip&#xff0c;并提供实时geoJson数据文件下载 可下载的数据包含省级geojson行政边界数据、市级geojson行政边界数据、区/县级geojson行政边界数据、省市区县街道行政编码四级联动数据&#xff0…

音视频之旅 - 基础知识

图像基础知识 像素 像素是图像的基本单元&#xff0c;一个个像素就组成了图像。你可以认为像素就是图像中的一个点。在下面这张图中&#xff0c;你可以看到一个个方块&#xff0c;这些方块就是像素 分辨率 图像&#xff08;或视频&#xff09;的分辨率是指图像的大小或尺寸。…

简单桶排序

#include<stdio.h> int main() { int a[11], i, j, t; for (i 0;i < 10;i) a[i] 0;//初始化为零 for (int i 1;i < 5;i)//循环输入5个数&#xff1b; { scanf("%d", &t);//把每一数读取到变量t中 a[t];/…

阿里云上传文件出现的问题解决(跨域设置)

跨域设置引起的问题 起因&#xff1a;开通对象存储服务后&#xff0c;上传文件限制在5M 大小&#xff0c;无法上传大文件。 1.查看报错信息 2.分析阿里云服务端响应内容 <?xml version"1.0" encoding"UTF-8"?> <Error><Code>Invali…

Excel VBA应用技巧

文章目录 第一章 Range &#xff08;单元格&#xff09;对象1. 单元格的引用方法1.1 使用Range 属性1.2 使用Cells 属性1.3 使用快捷记号1.4 使用Offset 属性1.5 使用Resizae 属性1.6 使用Union 方法1.7 使用UsedRange 属性1.8 使用CurrentRegion 属性 2. 选定单元格区域的方法…

NX二次开发自制UI界面大小设置

1、进入NX&#xff0c;点击“应用模块->更多->块UI样式编辑器”&#xff0c;进入UI编辑界面&#xff1b; 2、设置“Dialog->其他->DialogSizing”为Allow Resize 3、添加滚动窗口控件&#xff0c;设置Width、Height的值即可改变UI界面大小&#xff0c;注意&#x…

异常捕获后,如果事务回滚了,后面对数据库的操作需要加事务,不然对数据库的修改不会生效

异常捕获后&#xff0c;如果事务回滚了&#xff0c;后面对数据库的操作需要加事务&#xff0c;不然对数据库的修改不会生效

service层报错:Invalid bound statement (not found)

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

2023中医药国际传承传播大会暨中医药图片和非遗艺术展隆重揭幕

由世界针灸学会联合会、中新社国际传播集团、中国新闻图片网、中国民族医药学会、中国针灸学会联合主办的“2023中医药国际传承传播大会”3日在广东省深圳市举办&#xff0c;“中医药国际传承传播图片展”与“非遗艺术展”在大会举办期间开展迎客。会议聚焦非遗健康、非遗传承等…

MySQL生成UUID并去除-

uuid()函数 uuid() 函数可以使mysql生成uuid,但是uuid中存在-,如下图&#xff1a; 去除uuid的- 默认生成的uuid含有-&#xff0c;我们可以使用replace函数替换掉-&#xff0c;SQL如下 select replace(uuid(),"-","") as uuid;Insert语句中使用UUID 如果…

JAVA全栈开发 day18MySql03

一、复习 为什么要用数据库数据库好处数据库的发展史​ 层次模型​ 网状模型​ 关系模型&#xff08;二维表专门存储数据&#xff0c; 表与表的关联&#xff09;​ 表与表的关系&#xff1a; 1对1 &#xff0c;1对多&#xff0c;多对多​ 非关系模型关系模…

【ArcGIS Pro微课1000例】0051:创建数据最小几何边界范围(点、线、面数据均可)

本实例为专栏系统文章:创建点数据最小几何边界(范围),配套案例数据,持续同步更新! 文章目录 一、工具介绍二、实战演练三、注意事项一、工具介绍 创建包含若干面的要素类,用以表示封闭单个输入要素或成组的输入要素指定的最小边界几何。 工具界面及参数如下所示: 核心…

什么是高防IP,高防IP该如何选择。

高防IP&#xff0c;指的是高防御能力的IP地址。在互联网的世界里&#xff0c;网络安全问题成为一个重要的话题。作为一个用户&#xff0c;你是否曾遇到过被黑客攻击造成的网站瘫痪、信息泄露等问题&#xff1f;如果你是一个企业&#xff0c;你是否考虑过自己公司的网站和业务的…

大模型在企业知识库场景的落地思考

一、引言 在这个信息爆炸的时代&#xff0c;企业的知识库已不再是简单的数据堆砌&#xff0c;而是需要智能化、高效率的知识管理和利用。大模型作为AI领域的一个重要突破&#xff0c;正逐步成为企业知识库管理的强大助力。通过前面一段时间对于大模型在企业落地的深入调研和实…

Nature medicine癌症大肠癌分子残留病及辅助化疗的疗效

今天给同学们分享一篇文章“Molecular residual disease and efficacy of adjuvant chemotherapy in patients with colorectal cancer”&#xff0c;这篇文章发表在Nat Med期刊上&#xff0c;影响因子为82.9。 结果解读&#xff1a; 患者特征 在ctDNA分析中包括的1,039名患者…

Qt6 QRibbon 一键美化Qt界面

强烈推荐一个 github 项目&#xff1a; https://github.com/gnibuoz/QRibbon 作用&#xff1a; 在几乎不修改任何你自己代码的情况下&#xff0c;一键美化你的 UI 界面。 代码环境&#xff1a;使用 VS2019 编译 Qt6 GUI 程序&#xff0c;继承 QMainWindow 窗口类 一、使用方法 …

MyBatis-Plus学习笔记(无脑cv即可)

1.MyBatis-Plus 1.1特性 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑损耗小&#xff1a;启动即会自动注入基本 CURD&#xff0c;性能基本无损耗&#xff0c;直接面向对象操作强大的 CRUD 操作&#xff1a;内置通用 M…