vue 如何做一个动态的 BreadCrumb 组件,el-breadcrumb ElementUI
vue 如何做一个动态的 BreadCrumb 组件 el-breadcrumb ElementUI
一、ElementUI 中的 BreadCrumb 定义
elementUI 中的 Breadcrumb 组件是这样定义的
<template><el-breadcrumb separator="/"><el-breadcrumb-item :to="{ path: '/' }">主页</el-breadcrumb-item><el-breadcrumb-item>系统配置</el-breadcrumb-item><el-breadcrumb-item>基础配置</el-breadcrumb-item><el-breadcrumb-item>自动登录</el-breadcrumb-item></el-breadcrumb>
</template>
效果如图:
二、实现原理
我们需要实现的是,让它自己通过路由去填写这部分内容
原理是根据当前路由值,拆分成多个段,然后通过路由 path 去匹配对应的路由名称,再填入到上面的内容中即可。
比如:
1. 当前的路由值是 /system/normal-setup/auto-login
2. 通过拆分 /
生成一个数组
3. 依次匹配对应的路由名称
得到这个数组之后,依次去路由列表中匹配对应的路由名称
/system
系统配置/system/normal-setup
基础配置/system/normal-setup/auto-login
自动登录
4. 结果
这样就得到了一个 breadCrumb 数组,直接遍历这个数组,显示 BreadCrumb 即可
三、具体实现过程
知道了上面的实现原理,才会有具体的实现过程,这个过程还是有点麻烦的。
1. 处理路由数据
项目中用到的路由数据是这样的树形结构,路由数据的定义是这样的,里面的 children 可以嵌套任意层:
interface MenuEntity {id?: number | null,parent_id: number,name: string,icon?: string,type: EnumMenuType, // 1->目录 2->菜单 3->按钮 4->外链path: string,component?: string,visible: EnumMenuVisible, // 1->可见 2->隐藏 默认为1redirect: string,sort: number, // 默认为 20perm: string, // permissioncreated_at?: string,updated_at?: string,children?: MenuEntity[]
}
实际的数据是这样的:
{"name": "系统配置","id": 10,"parent_id": -1,"type": 1,"path": "/system","component": "","visible": 1,"redirect": "","perm": "","sort": 100,"icon": "Setting","created_at": "2024-02-26T14:55:12+08:00","updated_at": "2024-02-26T16:12:34+08:00","children": [{"name": "基础配置","id": 12,"parent_id": -1,"type": 1,"path": "/system/normal-setup","component": "","visible": 1,"redirect": "","perm": "","sort": 10,"icon": "CreditCard","created_at": "2024-02-26T15:20:15+08:00","updated_at": "2024-02-26T16:11:56+08:00","children": [{"name": "自动登录","id": 13,"parent_id": 12,"type": 2,"path": "/system/normal-setup/auto-login","component": "System/NormalSetup/AutoLoginSetup.vue","visible": 1,"redirect": "","perm": "","sort": 30,"icon": "User","created_at": "2024-02-26T15:24:18+08:00","updated_at": "2024-05-17T14:11:52+08:00","children": []},{"name": "系统更新","id": 28,"parent_id": 12,"type": 2,"path": "/system/normal-setup/system-update","component": "System/SystemUpdate.vue","visible": 1,"redirect": "","perm": "","sort": 50,"icon": "UploadFilled","created_at": "2024-02-26T16:19:49+08:00","updated_at": "2024-05-17T14:11:39+08:00","children": []},{"name": "申请厂家技术支持","id": 29,"parent_id": 12,"type": 2,"path": "/system/normal-setup/factory-help","component": "User/Space.vue","visible": 1,"redirect": "","perm": "","sort": 40,"icon": "SuitcaseLine","created_at": "2024-02-26T16:20:11+08:00","updated_at": "2024-03-27T09:04:20+08:00","children": []}]}]
}
为了好后续匹配 path 到路由名,需要将这个数据平化成一个数组,并构建一个 Map<path, RouteItem>
这样的一个 Map 数据,目的是当执行下面操作时,取到对应的路由数据
flatMenuPathNameMap.get('/system')// 最终取到这样的数据
{"name": "系统配置","id": 10,"parent_id": -1,"type": 1,"path": "/system","component": "","visible": 1,"redirect": "","perm": "","sort": 100,"icon": "Setting","created_at": "2024-02-26T14:55:12+08:00","updated_at": "2024-02-26T16:12:34+08:00",
}
平化树形数据、生成对应的 Map 数据结构:
/*** 菜单相关* 这里是单独放到了 pinia 中*/
export const useMenuStore = defineStore('menuStore', {state: () => ({menus: [] as Array<RouteRecordRaw>,flatMenuArray: [] as Array<MenuEntity>,flatMenuPathNameMap: new Map<string, string>()}),actions: {generateMenuArrayAndMap(){let menuString = localStorage.getItem('dataMenu')let menusCache = menuString ? JSON.parse(menuString) as Array<MenuEntity> : [] as Array<MenuEntity>let flatMenuArray = recursionMenuData(menusCache)this.flatMenuArray = flatMenuArraythis.flatMenuPathNameMap = new Map(flatMenuArray.map(item => [item.path, item.name]))// 递归方法,平化菜单数据function recursionMenuData(menuArray: Array<MenuEntity>){let tempArray: Array<MenuEntity> = []menuArray.forEach(item => {if (item.children && item.children.length > 0){tempArray = tempArray.concat(recursionMenuData(item.children))// 添加本身,并去除 children 属性delete item.childrentempArray.push(item)} else {tempArray.push(item)}})return tempArray}},}
})
使用的时候
import {useMenuStore, useProjectStore} from "./pinia";
const storeMenu = useMenuStore()
// 当执行下面的操作时就会补全 storeMenu.flatMenuArray 和 storeMenu.flatMenuPathNameMap
storeMenu.generateMenuArrayAndMap()
路由树的基础数据是这样的:
平化后的路由数组是这样的:
最终生成的 Map 数据是这样的:
2. 拆分当前路由 path,并匹配
比如当前路由是 /system/normal-setup/auto-login
,把它通过 /
拆分之后就是这样的结果
import {useRoute} from "vue-router";
const route = useRoute()
let routeSectionArray = route.path.split('/').filter(item => item !== '')
// 这样拆分之后,前面会多出一个空白的 "" ,所以这里剔除了它
接下来要做的就是通过上面的 routerSectionArray
生成下面的几个路由组合,再去之前生成的 Map 中匹配对应的路由名即可
/system
/system/normal-setup
/system/normal-setup/auto-login
匹配之后就是这样的结果
/system
系统配置/system/normal-setup
基础配置/system/normal-setup/auto-login
自动登录
代码是这样的:
import {useRoute} from "vue-router";
import {onMounted, ref} from "vue";
import {useMenuStore} from "@/pinia";const storeMenu = useMenuStore()
const route = useRoute()const breadCrumbArray = ref<Array<{name: string, path: string}>>([])onMounted(()=>{let routeSectionArray = route.path.split('/').filter(item => item !== '')console.log(routeSectionArray)routeSectionArray.forEach((_, index) => {let path = `/${routeSectionArray.slice(0,index + 1).join('/')}`let pathName = storeMenu.flatMenuPathNameMap.get(path)console.log('---',pathName, path)if (pathName){breadCrumbArray.value.push({name: pathName, path: path})}})
})
四、搭配其它组件构建页面
弄好上面的 BreadCrumb 组件之后,就可以不用再管它内部的内容了,它会自动根据当前路由值生成对应的内容。
这样我们就可以放心的把它放到页面结构中了。
比如我的页面主要结构是这样的:
Toolerbar.vue
<template><div class="tool-bar"><div class="left"><Breadcrumb/><slot name="left"/></div><div class="center"><slot name="center"/></div><div class="right"><slot name="right"/></div></div>
</template><script setup lang="ts">import Breadcrumb from "@/layout/Breadcrumb.vue";
</script><style scoped lang="scss">
.tool-bar{padding: 0 20px;align-items: center;min-height: 50px;display: flex;flex-flow: row wrap;justify-content: space-between;.left{display: flex;flex-flow: row nowrap;justify-content: flex-start;align-items: center;flex-shrink: 0;}.center{display: flex;flex-flow: row nowrap;justify-content: flex-start;align-items: center;flex-grow: 1;flex-shrink: 0;}.right{display: flex;flex-flow: row nowrap;justify-content: flex-start;align-items: center;flex-shrink: 0;}
}
</style>
Breadcrumb.vue
<template><el-breadcrumb separator="/"><el-breadcrumb-item :to="{ path: '/' }">主页</el-breadcrumb-item><el-breadcrumb-itemv-for="item in breadCrumbArray":key="item">{{ item.name }}</el-breadcrumb-item></el-breadcrumb>
</template><script setup lang="ts">
import {useRoute} from "vue-router";
import {onMounted, ref} from "vue";
import {useMenuStore} from "@/pinia";const storeMenu = useMenuStore()
const route = useRoute()defineProps( {height: { // 高度type: Number,default: 100}
})const breadCrumbArray = ref<Array<{name: string, path: string}>>([])onMounted(()=>{let routeSectionArray = route.path.split('/').filter(item => item !== '')routeSectionArray.forEach((_, index) => {let path = `/${routeSectionArray.slice(0,index + 1).join('/')}`let pathName = storeMenu.flatMenuPathNameMap.get(path)console.log('---',pathName, path)if (pathName){breadCrumbArray.value.push({name: pathName, path: path})}})
})</script><style lang="scss" scoped>
@import "../assets/scss/plugin";</style>
实际页面中使用时这样:
<template><Container><Toolbar><template #left></template><template #center></template><template #right></template></Toolbar><Content></Content></Container>
<template>
五、结果
相关文章:
vue 如何做一个动态的 BreadCrumb 组件,el-breadcrumb ElementUI
vue 如何做一个动态的 BreadCrumb 组件 el-breadcrumb ElementUI 一、ElementUI 中的 BreadCrumb 定义 elementUI 中的 Breadcrumb 组件是这样定义的 <template><el-breadcrumb separator"/"><el-breadcrumb-item :to"{ path: / }">主…...
FFmpeg播放视频
VS2017+FFmpeg6.2.r113110+SDL2.30.5 1.下载 ShiftMediaProject/FFmpeg 2.下载SDL2 3.新建VC++控制台应用 3.配置include和lib 4.把FFmpeg和SDL的dll 复制到工程Debug目录下,并设置调试命令...
重叠区间的求和
#摘抄 GetGeneLength/src/GetGeneLength/GetGeneLength.py at main PoShine/GetGeneLength GitHub def main(): """ Extract gene length based on featureCount calculation gene nonredundant exon length method. """ # 引…...
java包装类 及其缓存
Java 包装类(Wrapper Class)是将基本数据类型转换为对象的方式,每个基本数据类型在 java.lang 包中都有一个相应的包装类: Boolean 对应基本类型 boolean Character 对应基本类型 char Integer 对应基本类型 int Float 对应基本…...
大龄程序员的出路在哪里?
对于许多资深程序员而言,年龄并非职业发展的桎梏,反而如同陈年的美酒,随着时间的流逝愈发醇厚。他们手握的是丰富的经验和不断进阶的技能,而这些都为他们打开了职业发展的无数扇大门。让我们一同探索这些令人心动的可能性吧&#…...
Unity不用脚本实现点击按钮让另外一个物体隐藏
1.首先在场景中创建一个按钮和一个其他随便什么东西 2.点击按钮中的这个加号 3.然后将刚刚你创建的物体拖到这里来 4.然后依次点击下面这些给按钮绑定事件 5.运行游戏并点击按钮,就会发现拖进来的物体消失了 总结:如果按钮的功能单一,可以使用…...
RAG技术-为自然语言处理注入新动力
引言: 在自然语言处理(NLP)的领域中,RAG(Retrieval-Augmented Generation)技术以其独特的方式,正在改变我们与机器的交互方式。RAG技术结合了大语言模型的强大能力,使得机器在理解和…...
Docker安装ELK(简易版)
1、下载ELK镜像:打开终端,并执行以下命令以下载Elasticsearch、Logstash和Kibana的Docker镜像。您也可以根据需要选择其他版本: docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.6 docker pull docker.elastic.co/logstash…...
WPF项目实战视频《一》(主要为WPF基础知识)
1.WPF布局: Grid,stackPanel,wrapPanel,DockPanel,UniformGrid Grid 按行列布局, Grid.ColumnDefinitions列,Grid.RowDefinitions行 Grid.Row“0” Grid.Column“0” stackPanel 默认从上往下排…...
iOS ------ ARC的工作原理
一,ARC的概念 ARC (Automatic Reference Counting,自动引用计数) 是苹果公司在其编程语言(如 Objective-C 和 Swift)中的内存管理机制。ARC 通过编译器插入的代码自动管理对象的内存生命周期,减少了手动内存管理的复杂…...
【React】JSX基础
一、简介 JSX是JavaScript XML的缩写,它是一种在JavaScript代码中编写类似HTML模板的结构的方法。JSX是React框架中构建用户界面(UI)的核心方式之一。 1.什么是JSX JSX允许开发者使用类似HTML的声明式模板来构建组件。它结合了HTML的直观性…...
1分钟带你了解苹果手机删除照片恢复全过程
在日常使用苹果手机时,我们可能会不小心删除掉一些重要的照片,这让人非常烦恼。那么苹果手机怎么恢复删除的照片?下面小编将会向大家介绍苹果手机恢复删除的照片的方法,帮助大家轻松找回你丢失的照片。 一、利用“最近删除”文件夹…...
Ruby爬虫技术:深度解析Zhihu网页结构
在互联网时代,数据的价值日益凸显,尤其是在社交媒体和问答平台如Zhihu(知乎)上,用户生成的内容蕴含着丰富的信息和洞察。本文将深入探讨如何使用Ruby爬虫技术来解析Zhihu的网页结构,并获取有价值的数据。 …...
python中的re模块--正则表达式
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科 学的一个概念。正则表达式通常被用来检索、替换那些符合某个模 式(规则)的文本 re模块作用 通过使用…...
sqlalchemy反射视图
sqlalchemy反射视图 一个名为my_view的视图,使用SQLAlchemy来操作这个视图 from sqlalchemy import create_engine, MetaData# 创建数据库连接 engine = create_engine(数据库连接字符串)# 创建一个MetaData对象 metadata = MetaData()# 反射视图 metadata.reflect(bind=eng…...
最新版康泰克完整版- Kontakt v7.10.5 for Win和Mac,支持m芯片和intel,有入库工具
一。世界最受欢迎的采样器的新篇章 Native Instruments Kontakt是采样器领域的标准,您将获得高质量的滤波器,在这里您将找到经典的模拟电路和最现代的滤波器。每一个都可以根据您的口味进行定制,并且由于它,您可以获得前所未有的声…...
spring boot(学习笔记第十三课)
spring boot(学习笔记第十三课) 传统后端开发模式和前后端分离模式的不同,Spring Security的logout,invalidateHttpSession不好用,bug? 学习内容: 传统后端开发模式 vs 前后端分离模式Spring Security的logout功能inv…...
聊聊不再兼容安卓的鸿蒙
鸿蒙NExt已经确定不再兼容安卓系统,这意味着鸿蒙系统在更新迭代上将会展现出更加迅猛的速度。不过,这样的变化也给开发者们带来了不小的挑战。如今,鸿蒙的开发主要推荐使用的是ArkTS,而不是我们熟悉的Java SDK。对于大量习惯于使用…...
创建一个矩形,当鼠标进入这个矩形的时候,这个矩形边线变色,且鼠标变成手型
1.概要 创建一个矩形,当鼠标进入这个矩形的时候,这个矩形边线变色,且鼠标变成手型 2.代码 #include <QApplication> #include "customRectWidget.h" /** qt 6.7版, 创建一个矩形,当鼠标进入这个矩形…...
AI自动生成PPT哪个软件好?高效制作PPT优选这4个
7.15初伏的到来,也宣告三伏天的酷热正式拉开序幕~在这个传统的节气里,人们以各种方式避暑纳凉,享受夏日的悠闲时光。 而除了传统的避暑活动,我们还可以用一种新颖的方式记录和分享这份夏日的清凉——那就是通过PPT的方式将这一传…...
LruCache、Glide和SmartRefreshLayout使用总结
(一)Android智能下拉刷新框架-SmartRefreshLayout https://github.com/scwang90/SmartRefreshLayout?tabreadme-ov-file (二)LruCache使用 使用它可以进行图片的内存缓存 public class ImageLoaderUtil {private LruCache<St…...
Redis中数据分片与分片策略
概述 数据分片是一种将数据分割并存储在多个节点上的技术,可以有效提高系统的扩展性和性能。在Redis中,数据分片主要用于解决单个实例存储容量和性能瓶颈的问题。通过将数据分散存储到多个Redis节点中,可以将负载均衡到不同的服务器上&#…...
leetcode_169. 多数元素
leetcode_169. 多数元素 问题描述 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums …...
STM32 GPIO的工作原理
STM32的GPIO管脚有下面8种可能的配置:(4输入 2 输出 2 复用输出) (1)浮空输入_IN_FLOATING 在上图上,阴影的部分处于不工作状态,尤其是下半部分的输出电路,实际上是与端口处于隔离状态。黄色的高亮部分显示…...
板级调试小助手(2)ZYNQ自定义IP核构建属于自己的DDS外设
一、前言 在上期文章中讲述了小助手的系统结构和原理。在PYNQ的框架开发中,我们一般可以将PL端当做PS端的一个外设,通过读写寄存器的方式来操作外设的功能,就类似于在开发ARM和DSP中操作外设一样,不同时的是,我们可以通…...
vim+cscope+ctags
一、简单安装 1.安装cscope # apt install cscope 2.安装ctags # apt install ctags 3.taglist安装 下载Vim source code browser plugin - Browse /vim-taglist at SourceForge.net,解压和复制文件 # unzip taglist_46.zip# cp doc/taglist.txt /usr/share/…...
Java 8的变革:函数式编程和Lambda表达式探索
文章目录 一、函数接口二、Lambda表达式简介三、Lambda表达式外部参数四、Lambda范例五、Runnable Lambda表达式 一、函数接口 函数接口是一个具有单个抽象方法的接口,接口设计主要是为了支持 Lambda 表达式和方法引用,使得 Java 能更方便地实现函数式编…...
Java集合框架的内部揭秘:List、Set与Map的深潜之旅
Java集合框架是一套强大的工具,为开发者提供了灵活的数据管理方式。本文将深入剖析List、Set和Map的内部机制,通过详细的示例和扩展讨论,带你领略这些数据容器的真谛。 一、List:有序序列的深度剖析 List接口是一个可以包含重复…...
爬虫(二)——爬虫的伪装
前言 本文是爬虫系列的第二篇文章,主要讲解关于爬虫的简单伪装,以及如何爬取B站的视频。建议先看完上一篇文章,再来看这一篇文章。要注意的是,本文介绍的方法只能爬取免费视频,会员视频是无法爬取的哦。 爬虫的伪装 …...
空安全编程的典范:Java 8中的安全应用指南
文章目录 一、Base64 编码解码1.1 基本的编码和解码1.2 URL 和文件名安全的编码解码器1.3 MIME Base64编码和解码 二、Optional类三、Nashorn JavaScript 一、Base64 编码解码 1.1 基本的编码和解码 Base64 编码: 使用 Base64.getEncoder().encodeToString(origin…...
网站开发的系统需求/app拉新任务平台
13231313134121313131...
湖州 网站建设公司/免费发布产品信息的网站
header("Content-type:text/html; charsetUTF-8");/* ** 类名:YunxinSmsApi* 功能:云信接口请求类* 详细:构造云信短信接口请求,获取远程HTTP数据* 版本:1.3* 日期:2018-05-12* 说明:…...
秦皇岛手机网站制作价格/短视频推广渠道
方法1:感觉鲁棒性刚好些,但在两点拟合时出现 x1 无限接近 x2 或者 y1 无限接近 y2 时效果不好。 方法2:不存在方法1的问题,但是鲁棒性感觉不如方法1好。 FitLine1(std::vector<cv::Point2f> & SrcPts, MV_Line & …...
哪里专业做网站/如何建立网站 个人
pubsub,即订阅发布,在vue和react中常常被用于任意组件间的传值。 例如:订阅报纸: 1,交钱,说好地址,订阅哪一种报纸 2,邮递员送报纸 本文主要简述pubsub的基本使用流程。 1.在终端…...
深圳市住房和建设局电话/seo排名点击首页
数据仓库1、数据仓库的基本概念2、 数据仓库的主要特征3. 数据仓库与数据库区别4、数据仓库分层架构ODSETL为什么要对数据仓库分层?1、数据仓库的基本概念 数据仓库的英文名称为Data Warehouse,可简写为DW或DWH。数据仓库的目的是构建面向分…...
建设设计院网站/友情链接有用吗
很多人都觉得一定要找一个有趣的灵魂,因为自己的生活很无趣,有趣的灵魂会让你变得充满活力,姑娘们还想把日子过成诗,遇到一个爱运动爱旅游的男朋友,但是,姑娘,你看看你自己,大周末的…...