当前位置: 首页 > news >正文

Vue3 Element-plus el-menu无限级菜单组件封装

对于element中提供给我们的el-menu组件最多可以实现三层嵌套,如果多一层数据只能自己通过变量去加一层,如果加了两层、三层这种往往是行不通的,所以只能进行封装

效果图

 

 一、定义数据

MenuData.ts

export default [{id: "1",name: "第一级菜单",level: '1',child: [{id: "11",name: "第二级菜单",level: '1-1',child: [{id: "111",name: "第三级菜单",level: '1-1-1',child: [{id: "1111",name: "第四级菜单",level: '1-1-1-1',child: [{id: "11111",name: "第五级菜单",level: '1-1-1-1-1',child: []}]}]}]}]},{id: "2",name: "第一级同级菜单",level: '2',child: []}]

二、封装组件 

封装思想:

 1.对本身组件进行循环使用,如果有子集使用本身组件 把child数据传给自己

 2.如果没有子集 使用 el-menu-item

以下代码对setup( )函数和setup语法糖分别做了实现 

setup语法糖

<template><el-menu:default-active="defaultActive":unique-opened="true"class="el-menu-vertical-demo"><template v-for="item in menu"><!-- 如果有子集 --><template v-if="item.child && item.child.length > 0"><el-sub-menu:key="item.id":index="item.level":disabled="item.meta?.disabled":popper-append-to-body="false"><template #title><i :class="[item.meta?.icon]"></i><!-- 添加空格 表示下级--><span> {{ generateSpaces(item.level) }} </span><span slot="title"> {{ item.name }}</span></template><MenuTree:menu="item.child":defaultActive="defaultActive"@clickItem="clickItemHandle"/></el-sub-menu></template><!-- 如果没有子集 --><template v-else><el-menu-item:key="item.id":index="item.level":disabled="item.meta?.disabled":popper-append-to-body="false"@click="clickItemHandle(item)"><i :class="[item.meta?.icon]"></i><!-- 添加空格 表示下级--><span> {{ generateSpaces(item.level) }} </span><span slot="title">{{ item.name }}</span></el-menu-item></template></template></el-menu>
</template><script lang="ts" name="MenuTree" setup>
// 把下面代码变成setup语法糖的形式 
import type { PropType } from "vue";
import type { MenuItem } from "@/types/lesson";
// type 为了方便写成这样 可以根据自己项目设定typedefineProps({menu: {type: Array as unknown as PropType<any[]>,required: true,default: () => [],},defaultActive: {type: String as unknown as PropType<string>,required: true,default: [],},
});const emit = defineEmits(["update-active-path", "clickItem"]);// 返回的空格字符串 用于显示菜单层级 
const generateSpaces = (level: string) => {let str = "";level.split("")  .filter((it) => it != "-") .forEach(() => {str += " ";});return str;
};// 点击当前菜单项
const clickItemHandle = (item: MenuItem) => {emit("clickItem", item);
};
</script><style scoped lang="less">
.el-menu {width: 288px;
}
</style>

setup函数

<template><el-menu :default-active="defaultActive"  :unique-opened="true"   class="el-menu-vertical-demo"  ><template v-for="item in menu"><template v-if="item.child && item.child.length > 0"><el-sub-menu :key="item.id":index="item.level":disabled="item.meta?.disabled":popper-append-to-body="false"><template #title><i :class="[item.meta?.icon]"></i><!-- 添加空格 表示下级--><span> {{ generateSpaces(item.level) }} </span><span slot="title"> {{ item.name }}</span></template><MenuTree :menu="item.child" :defaultActive="defaultActive"  @clickItem="clickItemHandle"  /></el-sub-menu></template><template v-else><el-menu-item :key="item.id":index="item.level":disabled="item.meta?.disabled":popper-append-to-body="false"@click="clickItemHandle(item)"><i :class="[item.meta?.icon]"></i><!-- 添加空格 表示下级--><span> {{ generateSpaces(item.level) }} </span><span slot="title">{{ item.name }}</span></el-menu-item></template></template></el-menu>
</template><script lang="ts">
import { defineComponent, toRefs } from 'vue';
import type { PropType } from 'vue'
import type {MenuItem} from '@/types/lesson'
export default defineComponent({name: 'MenuTree',props: {menu: {type: Array as unknown as PropType<any[]>,required: true,default: () => [],},defaultActive: {type: String as unknown as PropType<string>,required: true,default: '',},},emits: ['update-active-path','clickItem'],setup(props, context) {const { menu, defaultActive } = toRefs(props);const generateSpaces = (level:string) => {let str = ''level.split('').filter(it=>it!='-').forEach(() => {str += ' '})return str}const clickItemHandle = (item:MenuItem) => {context.emit('clickItem', item)}return {clickItemHandle,menu,defaultActive,generateSpaces,}},
});
</script><style scoped lang="less">.el-menu {width: 288px;}
</style>

 type就不补充了 可根据自己项目定义,可临时改成any

三、使用组件

<template><MenuTree:menu="menuList":defaultActive="defaultActive"@clickItem="handleMenuClick":update-click="handleMenuClick"/>
</template><script setup lang="ts">
import MenuTree from "./components/MenuTree.vue";
import type {MenuItem} from '@/types/lesson'
import menuData from './MenuData'const defaultActive = ref<string>(''); // "1-1-1-1" 默认选中的数据
const menuList = ref(menuData)const handleMenuClick = (item:MenuItem) => {console.log('父组件',item);
};
</script>

补充default-active变量,如果一开始想默认点开第一层的数据 就需要找规律啦

拿到所有的level,通过接口方式返给你 自己平铺拿到所有的level也好 

例如数据格式:

let arr = [  "1-1","1-1-1","1-1-1-1","1-1-1-2","1-1-1-3","1-1-1-4","1-1-1-5","1-1-1-6","1-1-2","1-1-2-1"
]

 想要的结果就是 最长且相同数字最多的元素 1-1-1-1

arr.sort((a,b)=> b.split('-').length - a.split('-').length)[0]

使用split防止有些字符串是10、11 两位数字的

相关文章:

Vue3 Element-plus el-menu无限级菜单组件封装

对于element中提供给我们的el-menu组件最多可以实现三层嵌套&#xff0c;如果多一层数据只能自己通过变量去加一层&#xff0c;如果加了两层、三层这种往往是行不通的&#xff0c;所以只能进行封装 效果图 一、定义数据 MenuData.ts export default [{id: "1",name…...

( “树” 之 BST) 669. 修剪二叉搜索树 ——【Leetcode每日一题】

二叉查找树&#xff08;BST&#xff09;&#xff1a;根节点大于等于左子树所有节点&#xff0c;小于等于右子树所有节点。 二叉查找树中序遍历有序。 669. 修剪二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&…...

【C语言】浅涉结构体(声明、定义、类型、定义及初始化、成员访问及传参)

简单不先于复杂&#xff0c;而是在复杂之后。 目录 1. 结构体的声明 1.1 结构体的基础知识 1.2 结构的声明 1.3 结构成员的类型 1.4 结构体变量的定义和初始化 2. 结构体成员的访问 3. 结构体传参 1. 结构体的声明 1.1 结构体的基础知识 结构是一些值的集合&…...

设计模式-结构型模式之装饰模式

3. 装饰模式 3.1. 模式动机 一般有两种方式可以实现给一个类或对象增加行为&#xff1a; 继承机制 使用继承机制是给现有类添加功能的一种有效途径&#xff0c;通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的&#xff0c;用户不能…...

【Chatgpt4 教学】 NLP(自然语言处理)第九课 朴素贝叶斯分类器的工作原理 机器学习算法

我在起&#xff0c;点更新NLP自然语言处理》《王老师带我成为救世主》 为啥为它单独开章&#xff0c;因为它值得&#xff0c;它成功的让我断了一更&#xff0c;让我实践了自上而下找能够理解的知识点&#xff0c;然后自下而上的学习给自己的知识升级&#xff0c;将自己提升到能…...

基于html+css的图片展示17

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…...

Jupyter Notebook小知识

目录 1 快捷键1.1 常用快捷键1.2 魔法函数 2 常用快捷键2.1 模式切换2.2 命令模式快捷键2.3 编辑模式快捷键3 Matplotlib绘图 4 小技巧4.1 文件默认目录的查看以及更改4.2 更改主题颜色 5 其它5.1 python中 r, b, u, f 的含义5.2 f/format():格式化操作 6 常见问题6.1 查看模块…...

redis原理及进化之路

Redis 的主从复制经历了多次演进&#xff0c;本文将从最基本的原理和实现讲起&#xff0c;并层层递进&#xff0c;逐步呈现 Redis 主从复制的演进历史。大家将了解到 Redis 主从复制的原理&#xff0c;以及各个改进版本解决了什么问题&#xff0c;并最终看清 Redis 7.0 主从复制…...

ai智能写作助手-ai自动写作软件

为什么要用ai智能写作工具 在数字化时代&#xff0c;AI&#xff08;人工智能&#xff09;技术已经被广泛应用于各种领域&#xff0c;其中之一是写作。AI智能写作工具是利用自然语言处理技术和机器学习算法来生成高质量的文章、博客、新闻稿等。这些工具不仅提供了便捷、高效的…...

redis持久化

redis提供两种方式进行持久化&#xff0c;一种是RDB持久化&#xff08;原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化&#xff09;&#xff0c;另外一种是AOF持久化&#xff08;原理是将Reids的操作日志以追加的方式写入文件&#xff09;。那么这两种持久化方…...

Vue项目基于driverjs实现新用户导航

引导页就是当用户第一次或者手动进行触发的时候&#xff0c;提示给用户当前系统的模块介绍&#xff0c;比如哪里是退出&#xff0c;哪里是菜单等等相应的操作。 无论是开发 APP 还是 web 应用&#xff0c;新手引导都是一个很常见的需求&#xff0c;一般在这2个方面需要新手引导…...

自编码器简单介绍—使用PyTorch库实现一个简单的自编码器,并使用MNIST数据集进行训练和测试

文章目录 自编码器简单介绍什么是自编码器&#xff1f;自动编码器和卷积神经网络的区别&#xff1f;如何构建一个自编码器&#xff1f;如何训练自编码器&#xff1f;如何使用自编码器进行图像压缩&#xff1f;总结使用PyTorch构建简单的自动编码器第一步&#xff1a;导入库和数…...

redis单机最大并发量

redis单机最大并发量 布隆过滤器多级缓存客户端缓存应用层缓存Expires和Cache-Control的区别Nginx缓存管理 服务层缓存进程内缓存进程外缓存 缓存数据一致性问题的解决引入多级缓存设计的时刻 Redis的速度非常的快,单机的Redis就可以⽀撑 每秒十几万的并发,相对于MySQL来说,性…...

MTLAB绘图

这里写目录标题 一、图例1、散点图 二、绘图1、总体图形参数2、坐标、图框、网格图框去上右边框小刻度网格坐标范围和刻度控制旋转 坐标、刻度 3、图例图例位置和方向 Location和Orientation图例加标题 、分多列 4、文本 字、字体、字号5、线型 符号6、颜色栏 colorbar7、颜色8…...

自媒体必备素材库,免费、商用,赶紧马住~

自媒体经常需要用到各类素材&#xff0c;本期就给大家安利6个自媒体必备的素材网站&#xff0c;免费、付费、商用都有&#xff0c;建议收藏起来~ 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库可以找到设计、办公、图片、视频、音频等各种素材。视频素…...

ESP32设备驱动-BMP388气压传感器驱动

BMP388气压传感器驱动 文章目录 BMP388气压传感器驱动1、BMP388介绍2、硬件准备3、软件准备4、驱动实现1、BMP388介绍 BMP388 是一款非常小巧、低功耗和低噪声的 24 位绝对气压传感器。 它可以实现精确的高度跟踪,特别适合无人机应用。 BMP388 在 0-65C 之间的同类最佳 TCO,…...

攻防世界-Reversing-x64Elf-100

Reversing-x64Elf-100 18最佳Writeup由 yuchouxuan 提供 收藏 反馈 难度&#xff1a;1 方向&#xff1a;Reverse 题解数&#xff1a;15 解出人数&#xff1a;2460 题目来源: 题目描述: 暂无 note:undefined8 FUN_004006fd(long param_1){int local_2c;char *local_28 …...

C/C++每日一练(20230419)

目录 1. 插入区间 &#x1f31f;&#x1f31f;&#x1f31f; 2. 单词拆分 &#x1f31f;&#x1f31f; 3. 不同路径 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日…...

[自注意力神经网络]Mask Transfiner网络-论文解读

本文为CVPR2022的论文。国际惯例&#xff0c;先贴出原文和源码&#xff1a; 原论文地址https://arxiv.org/pdf/2111.13673.pdf源码地址https://github.com/SysCV/transfiner 一、概述 传统的Two-Stage网络&#xff0c;如Mask R-CNN虽然在实例分割上取得了较好的效果&#xff…...

漫画:是喜,还是悲?AI竟帮我们把Office破活干完了

图文原创&#xff1a;亲爱的数据 国产大模型烈火制造。阿里百度字节美团各科技大佬不等闲。 大模型嘛&#xff0c;重大工程&#xff0c;对我等“怀保小民”来说&#xff0c;只关心怎么用&#xff0c;不关心怎么造。 我来介绍一下自己&#xff0c;我是一个写稿男团组合的成员&am…...

国产 KVM 兼容痛点及全国产定制方案

作为标准 KVM、军工加固 KVM 产品经理&#xff0c;在一些项目落地过程中&#xff0c;我发现一个普遍问题&#xff1a;国产服务器、国产系统越来越普及&#xff0c;但市面上绝大多数 KVM 切换器&#xff0c;兼容性问题频发&#xff0c;已经成为运维短板。一、当前 KVM 最常见的兼…...

TranslucentTB:3分钟打造Windows任务栏透明效果的终极指南

TranslucentTB&#xff1a;3分钟打造Windows任务栏透明效果的终极指南 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 想让你的Windows桌…...

基于树莓派与ROS的桌面机器人开发:从硬件组装到AI集成实战

1. 项目概述&#xff1a;一个“会思考”的桌面机器人伙伴最近在机器人爱好者圈子里&#xff0c;一个名为“Wall-E”的开源项目热度不低。这可不是那个动画电影里可爱的垃圾处理机器人&#xff0c;而是一个由SRA-VJTI团队开发的、运行在树莓派上的桌面级智能机器人项目。我第一次…...

深度解析Beyond Compare 5密钥生成:从逆向工程到高效激活的实用指南

深度解析Beyond Compare 5密钥生成&#xff1a;从逆向工程到高效激活的实用指南 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen 在软件授权验证领域&#xff0c;Beyond Compare 5的RSA加密机制一…...

PyTorch实战:手写Sobel与Laplace算子实现图像边缘检测

1. 图像边缘检测与卷积算子基础 第一次接触图像处理时&#xff0c;我对"边缘检测"这个概念特别好奇。简单来说&#xff0c;边缘就是图像中物体轮廓或纹理变化明显的区域。想象一下用铅笔描边一幅画的过程&#xff0c;边缘检测就是让计算机自动完成这个工作。 为什么边…...

STM32F407 USART3串口DMA不定长接收与中断发送实战:从零构建高效通信框架

1. 为什么需要DMAUSART组合方案 在嵌入式开发中&#xff0c;串口通信就像设备与外界对话的"嘴巴"和"耳朵"。传统的中断方式就像每次只说一个字就要停下来等回应&#xff0c;效率实在太低。想象一下&#xff0c;如果你跟朋友聊天&#xff0c;每说一个字就要…...

别再复制官网代码了!Vue + Ant Design 图标与分隔符的本地化实战(附避坑指南)

Vue Ant Design 图标与分隔符的本地化实战指南 在Vue项目中使用Ant Design Vue组件库时&#xff0c;很多开发者习惯直接从官网复制示例代码。然而&#xff0c;这种"拿来主义"常常导致项目运行时出现图标不显示、样式依赖CDN资源等问题。本文将带你从零开始&#xff…...

BoxLite-AI:轻量级AI应用开发框架,10分钟将模型部署为Web服务

1. 项目概述&#xff1a;BoxLite-AI&#xff0c;一个轻量级AI应用开发框架最近在AI应用开发领域&#xff0c;一个趋势越来越明显&#xff1a;大家不再满足于仅仅调用API&#xff0c;而是希望将AI能力更深度、更灵活地集成到自己的业务流中。但一提到“深度集成”&#xff0c;很…...

Android AI助手开发实战:基于MVVM与OpenAI API的AnywhereGPT项目解析

1. 项目概述与核心价值最近在折腾移动端AI应用&#xff0c;发现一个挺有意思的开源项目&#xff0c;叫AnywhereGPT-Android。简单来说&#xff0c;它就是一个让你能在Android手机上&#xff0c;通过调用OpenAI的API&#xff08;比如GPT-3.5/4&#xff09;或者本地部署的模型&am…...

初创团队如何利用Taotoken低成本启动AI功能并灵活扩展

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 初创团队如何利用Taotoken低成本启动AI功能并灵活扩展 对于初创团队而言&#xff0c;在产品中引入人工智能能力是提升竞争力的关键…...