我一人全干!之二,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,一经查实,立即删除!

相关文章

探索鸿蒙_ArkTs开发语言

ArkTs 在正常的网页开发中&#xff0c;实现一个效果&#xff0c;需要htmlcssjs三种语言实现。 但是使用ArkTs语言&#xff0c;就能全部实现了。 ArkTs是基于TypeScript的&#xff0c;但是呢&#xff0c;TypeScript是基于javascript的&#xff0c;所以ArkTs不但能完成js的工作&a…

传导电流密度方向与磁矢位方向相同

矢量位 A ⃗ \vec A A 由于磁感应强度 B ⃗ \vec B B 是无源场&#xff0c;散度为0&#xff0c; ∇ ⋅ B ⃗ 0 \nabla \cdot \vec B 0 ∇⋅B 0, 因此引入矢量位 A ⃗ \vec A A , 满足 ∇ A ⃗ B ⃗ \begin{align} \nabla \times \vec A &\vec B \end{align} ∇A ​B ​…

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 使用动态表单组件 …

在开发软件KEIL MDK和IAR开发工程里面打印行号、文件名、函数名、时间

最近应用固件没有时间记录&#xff0c;分别请那个是最新的&#xff08;在没有版本区别的情况下&#xff09;&#xff0c;有个办法记录编译时间即可&#xff0c;记录笔记以便查看 在软件工程里面直接用宏 __FILE __ 当前程序文件名的字符串 __FUNCTION __ 当前函数的名字字符串 …

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

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

优化的 MCM-GPU 比具有相同 SM 总数和 DRAM 带宽的同等配备的多 GPU 系统快 26.8%。

MCM-GPU: Multi-chip-module GPUs for Continued Performance Scalability 抽象&#xff1a; 从历史上看&#xff0c;基于 GPU 的高性能计算的改进与晶体管缩放紧密相连。随着摩尔定律的减慢&#xff0c;每个芯片的晶体管数量不再以历史速度增长&#xff0c;单个单片GPU的性能…

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

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

Python-元组详解

注意&#xff1a;列表是方括号【】&#xff0c;元组是圆括号&#xff08;&#xff09;&#xff0c;这里要分清。 创建元组 1、a () 2、b tuple() a () b tuple() 2、可以指定初始值 a (1,2,3,4) a (1,2,3,4) 3、元素可以是任意类型 a (1,2,3,4,hello) a (1,2,3,4…

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

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

免费,开源的充电站(充电桩)软件技术栈

关于 PIONIX&#xff1a; PIONIX 成立于 2021 年&#xff0c;总部位于德国巴特申博恩&#xff0c;已迅速成为该领域的推动者。PIONIX 牵头开发了 Linux 基金会能源项目 EVERest——一个尖端、免费、开源的充电站软件堆栈。值得注意的是&#xff0c;OCPP 是该计划的重要组成部分…

音视频之旅 - 基础知识

图像基础知识 像素 像素是图像的基本单元&#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];/…

edge 浏览器妙用你好

1 文字无法复制 在网络地址前加 read: 【即将失效】16个Edge隐藏绝技&#xff0c;你未必全知道&#xff01;&#xff01;&#xff01;_哔哩哔哩_bilibili

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

跨域设置引起的问题 起因&#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;“中医药国际传承传播图片展”与“非遗艺术展”在大会举办期间开展迎客。会议聚焦非遗健康、非遗传承等…

序列构成的数组

容器序列   list、tuple 和 collections.deque 这些序列能存放不同类型的数据。 扁平序列   str、bytes、bytearray、memoryview 和 array.array&#xff0c;这类序列只能容纳一种类型。 容器序列存放的是它们所包含的任意类型的对象的引用&#xff0c;而扁平序列里存放的…