在使用element plus 時,最初要使用的就是導航組件了,官網上看到的也就是寫死的一級/二級導航,那么如何設計一個無限級且動態的導航呢?毋庸置疑,遞歸。廢話不多說,直接看代碼和效果:
代碼:

目錄結果
SidebarItem.vue
<template><el-menu-item :index="item ? item.url : ''" v-if="!item || !item.children || item.children.length === 0">{{ item?.menuName }}</el-menu-item><el-sub-menu :index="item ? item.id : ''" v-else><template #title><span class="tab">{{ item?.menuName }}</span></template><div v-for="(child, index) in item?.children" :key="index"><template v-if="child.children && child.children.length > 0"><sidebar-item :key="child.id" :item="child" /></template><el-menu-item v-else :index="child.url"><span class="tab sub">{{ child.menuName }}</span></el-menu-item></div></el-sub-menu>
</template><script lang="ts" setup>
import { PropType, toRefs } from 'vue';
import { MenuNode } from '../../../../model/menuNode';const props = defineProps({collapse: {type: Boolean,default: true},item: {type: Object as PropType<MenuNode>,},
});const { item } = toRefs(props);
</script><style lang="scss"></style>
Index.vue
<div class="nav"><el-scrollbar class="scrollbar"><el-menu class="menu" @open="handleOpen" @close="handleClose" mode="horizontal" router><SidebarItem v-for="route in menuList" :key="route.id" :item="route"></SidebarItem></el-menu></el-scrollbar></div>
測試數據:
export default [{'id': '001','parentId': '0','menuName': '首頁','url': '/dashboard','sortNo': 1,'icon': 'Aim'},{'id': '002','parentId': '0','menuName': '表格','url': '/charts','sortNo': 4,'icon': 'ArrowDownBold'},{'id': '0021','parentId': '002','menuName': '樹狀圖','url': '/charts/charts1','sortNo': 4,'icon': 'ArrowDownBold'},{'id': '0022','parentId': '002','menuName': '餅狀圖','url': '/charts/charts2','sortNo': 4,'icon': 'ArrowDownBold'},{'id': '003','parentId': '0','menuName': '測試四級1','url': '/dashboard','menuType': 1,'sortNo': 2,'icon': 'Aim'},{'id': '0031','parentId': '003','menuName': '測試四級2','url': '/dashboard','menuType': 1,'sortNo': 2,'icon': 'Aim'},{'id': '00311','parentId': '0031','menuName': '測試四級3','url': '/dashboard','menuType': 1,'sortNo': 2,'icon': 'Aim'},{'id': '003111','parentId': '00311','menuName': '測試四級4','url': '/dashboard','menuType': 1,'sortNo': 2,'icon': 'Aim'},
];
這里需要將數組轉換成樹形結構,也附上代碼好了(純手工輸出,有bug還望見諒):
/** @Author: zzh* @Date: 2022-03-01 14:39:16* @LastEditors: zzh* @LastEditTime: 2022-04-10 17:13:03* @Description: 數據轉換幫助類* @FilePath: \zh-admin\src\utils\dataConvert.ts*/import { MenuNode } from '../model/menuNode';// 由于菜單數據并非一顆樹,而是多棵樹組成的數據,顧當成由樹組成的數組的處理
const convertMenuArrToTree = (array: Array<MenuNode>) => {const rootMenus = array.filter(x => x.parentId === '0');const childrenMenus = array.filter(x => x.parentId !== '0');for (let i = 0; i < rootMenus.length; i++) {if (childrenMenus.find(x => x.parentId === rootMenus[i].id)) {rootMenus[i].children = getRootMenuChild(rootMenus[i].id, childrenMenus);} else {rootMenus[i].children = [];}}return rootMenus;
};const getRootMenuChild = (id: string, childrenMenus: Array<MenuNode>): Array<MenuNode> => {const menus = childrenMenus.filter(x => x.parentId === id);for (let i = 0; i < menus.length; i++) {if (childrenMenus.find(x => x.parentId === menus[i].id)) {menus[i].children = getRootMenuChild(menus[i].id, childrenMenus);} else {menus[i].children = [];}}return menus;
};export {convertMenuArrToTree,
};
展示結果:

?