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>

五、结果

在这里插入图片描述

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

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

相关文章

爬虫的概念

爬虫&#xff08;Web Crawler 或 Web Spider&#xff09;是一种自动化脚本或程序&#xff0c;用于浏览万维网&#xff08;World Wide Web&#xff09;并抓取网页上的信息。它们按照设定的规则自动地访问互联网上的网页&#xff0c;提取所需的数据&#xff0c;如文本、图片、视频…

搭建七日杀服务端系统选择,系统如何选择

《七日杀》是一款集合了第一人称射击、恐怖生存、塔防与角色扮演要素于一身的开放世界僵尸游戏。玩家需要在美国亚历桑纳地区作为幸存者生存&#xff0c;并探究整个事件背后的真相。对于喜欢这款游戏的玩家来说&#xff0c;搭建自己的专属服务器不仅能降低延迟&#xff0c;还能…

精通Python数据可视化:Matplotlib柱状图、直方图与饼状图实战解析

精通Python数据可视化&#xff1a;Matplotlib柱状图、直方图与饼状图实战解析 引言 在数据分析和科学研究中&#xff0c;数据可视化扮演着至关重要的角色。Matplotlib是Python中一个广泛使用的绘图库&#xff0c;它提供了丰富的绘图功能和灵活的定制选项。本文将详细介绍如何…

ubuntu 可以直接在图像界面打开命令行吗

是的&#xff0c;Ubuntu&#xff08;以及其他许多Linux发行版&#xff09;允许用户直接在图形界面&#xff08;GUI&#xff09;中打开命令行界面。这通常通过打开一个终端模拟器应用程序来实现&#xff0c;该应用程序提供了一个命令行窗口&#xff0c;用户可以在其中输入和执行…

修改文件的默认打开方式

修改文件的默认打开方式 选中文件&#xff0c;右击&#xff0c;选择属性&#xff0c;如图然后点击更改&#xff0c;选择想要的打开方式&#xff0c;再依次点击 应用、保存 即可&#xff0c;如图

Linux 环境下整体备份迁移 Docker 镜像及数据教程

1. 介绍 本教程将引导您如何在 Linux 环境下备份和迁移 Docker 镜像及其数据。我们将逐步介绍相关步骤&#xff0c;包括 Docker 镜像的导出和导入、数据卷的备份和恢复等。通过本教程&#xff0c;您将能够轻松掌握 Docker 容器的迁移操作。 2. 前置准备 在开始之前&#xff…

Redis中数据分片与分片策略

概述 数据分片是一种将数据分割并存储在多个节点上的技术&#xff0c;可以有效提高系统的扩展性和性能。在Redis中&#xff0c;数据分片主要用于解决单个实例存储容量和性能瓶颈的问题。通过将数据分散存储到多个Redis节点中&#xff0c;可以将负载均衡到不同的服务器上&#…

Visual Studio使用——在vs中给vb.net项目添加新的窗口:新建的方式、添加已有窗口的方式

目录 引出Visual Studio使用vb添加新的窗体自定义代码片段vs显示所有文件 总结Idea安装和使用0.Java下载 和 IDEA工具1.首次新建项目2.隐藏文件不必要显示文件3.目录层级设置4.Settings设置选择idea的场景提示代码不区分大小写 取消git的代码作者显示 引出 Visual Studio使用—…

基于Vue CLI 3构建Vue3项目(Vue2也可参考)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Android Framework学习笔记(4)----Zygote进程

Zygote的启动流程 Init进程启动后&#xff0c;会加载并执行init.rc文件。该.rc文件中&#xff0c;就包含启动Zygote进程的Action。详见“RC文件解析”章节。 根据Zygote对应的RC文件&#xff0c;可知Zygote进程是由/system/bin/app_process程序来创建的。 app_process大致处…

PHP手边酒店多商户版平台小程序系统源码

&#x1f3e8;【旅行新宠】手边酒店多商户版小程序&#xff0c;一键解锁住宿新体验&#xff01;&#x1f6cc; &#x1f308;【开篇&#xff1a;旅行新伴侣&#xff0c;尽在掌握】&#x1f308; 还在为旅行中的住宿选择而纠结吗&#xff1f;是时候告别繁琐的搜索和比价过程&a…

MT6985(天玑9200)芯片性能参数_MTK联发科旗舰5G移动平台处理器

MT6985天玑 9200 旗舰移动平台拥有专业级影像、沉浸式游戏和先进移动显示技术&#xff0c;以及更快捷、覆盖更广的 5G 和 支持 Wi-Fi 7 连接&#xff0c;具有高性能、高能效、低功耗表现。率先采用 Armv9 性能核&#xff0c;全部支持纯 64 位应用&#xff0c;开启高能效架构设计…

【数据库学习】java数据库开发:sql解析之jsqlparser

1&#xff0c;概念 1&#xff09; SQL 解析器 用于处理 SQL 查询语句的解析和分析。 场景&#xff1a; 数据库客户端开发&#xff0c;解析用户输入的sql语法并执行。自定义sql解析和执行逻辑。 标准的数据库接口&#xff08;如 JDBC&#xff09;无法完全满足需求时&#xff…

音频数据集

1 多语言 Mozilla Common Voice 下载地址&#xff1a;https://voice.mozilla.org/data 时长&#xff1a;1965小时&#xff08;目前为止&#xff09; 最早2017年发布&#xff0c;持续更新&#xff0c;该基金会表示&#xff0c;通过 Common Voice 网站和移动应用&#xff0c;他们…

搞定前端面试题——ES6同步与异步机制、async/await的使用以及Promise的使用!!!

文章目录 同步和异步async/awaitPromisePromise的概念 同步和异步 ​ 同步&#xff1a;代码按照编写顺序逐行执行&#xff0c;后续的代码必须等待当前正在执行的代码完成之后才能执行&#xff0c;当遇到耗时的操作&#xff08;如网络请求等&#xff09;时&#xff0c;主线程会…

Java二十三种设计模式-抽象工厂模式(3/23)

抽象工厂模式&#xff1a;复杂系统的灵活构建者 引言 在软件开发中&#xff0c;抽象工厂模式是一种提供接口以创建相关或依赖对象族的创建型设计模式。这种模式允许客户端使用一个共同的接口来创建不同的产品族&#xff0c;而无需指定具体类。 基础知识&#xff0c;java设计模…

SpringBoot日常:常用数据类型比较

文章目录 前言基本类型引用类型date类型比较LocalDate类型比较LocalDateTime类型比较Bigdecimal类型比较对象类型比较 前言 在Java中,我们一般分为基本类型的比较和引用类型的比较&#xff0c;下面按照这两个大分类梳理一下日常用到的类型比较 基本类型 基本数据类型比较主要…

算法 —— LRU算法

算法 —— LRU算法 LRULRU算法的工作原理&#xff1a;实现方法&#xff1a;性能考虑&#xff1a; 模拟过程splice函数对于std::list和std::forward_list基本语法&#xff1a;功能描述&#xff1a; 示例&#xff1a;注意事项&#xff1a; 如果大家已经学习过了Cache的替换算法和…

ElementUIV12相关使用方法

今日内容 零、 复习昨日 零、 复习昨日 一、Element UI Element&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库 官网&#xff1a; https://element.eleme.cn/#/zh-CN Element Plus,基于 Vue 3&#xff0c;面向设计师和开发者的组件库 官网: htt…

C语言--递归

曾经有一个段子&#xff1a;上大学时&#xff0c;我们的c语言老师说&#xff1a;学c时&#xff0c;如果有50%的同学死在了循环上面&#xff0c;那么就有90%的同学死在了递归上面。接下来&#xff0c;就来看看递归是怎么个事&#xff1f; 一.递归的介绍 递归是指一个函数直接或…