• Element Plus/vue3 无限级导航实现


    在使用element plus 时,最初要使用的就是导航组件了,官网上看到的也就是写死的一级/二级导航,那么如何设计一个无限级且动态的导航呢?毋庸置疑,递归。废话不多说,直接看代码和效果:
    代码:

    8784c28b7e48b0055253bc69c854d4d9.png
    目录结果

    SidebarItem.vue

    1. <template>
    2. <el-menu-item :index="item ? item.url : ''" v-if="!item || !item.children || item.children.length === 0">
    3. {{ item?.menuName }}
    4. </el-menu-item>
    5. <el-sub-menu :index="item ? item.id : ''" v-else>
    6. <template #title>
    7. <span class="tab">{{ item?.menuName }}</span>
    8. </template>
    9. <div v-for="(child, index) in item?.children" :key="index">
    10. <template v-if="child.children && child.children.length > 0">
    11. <sidebar-item :key="child.id" :item="child" />
    12. </template>
    13. <el-menu-item v-else :index="child.url">
    14. <span class="tab sub">{{ child.menuName }}</span>
    15. </el-menu-item>
    16. </div>
    17. </el-sub-menu>
    18. </template>
    19. <script lang="ts" setup>
    20. import { PropType, toRefs } from 'vue';
    21. import { MenuNode } from '../../../../model/menuNode';
    22. const props = defineProps({
    23. collapse: {
    24. type: Boolean,
    25. default: true
    26. },
    27. item: {
    28. type: Object as PropType<MenuNode>,
    29. },
    30. });
    31. const { item } = toRefs(props);
    32. </script>
    33. <style lang="scss"></style>

    Index.vue

    1. <div class="nav">
    2. <el-scrollbar class="scrollbar">
    3. <el-menu class="menu" @open="handleOpen" @close="handleClose" mode="horizontal" router>
    4. <SidebarItem v-for="route in menuList" :key="route.id" :item="route"></SidebarItem>
    5. </el-menu>
    6. </el-scrollbar>
    7. </div>

    测试数据

    1. export default [
    2. {
    3. 'id': '001',
    4. 'parentId': '0',
    5. 'menuName': '首页',
    6. 'url': '/dashboard',
    7. 'sortNo': 1,
    8. 'icon': 'Aim'
    9. },
    10. {
    11. 'id': '002',
    12. 'parentId': '0',
    13. 'menuName': '表格',
    14. 'url': '/charts',
    15. 'sortNo': 4,
    16. 'icon': 'ArrowDownBold'
    17. },
    18. {
    19. 'id': '0021',
    20. 'parentId': '002',
    21. 'menuName': '树状图',
    22. 'url': '/charts/charts1',
    23. 'sortNo': 4,
    24. 'icon': 'ArrowDownBold'
    25. },
    26. {
    27. 'id': '0022',
    28. 'parentId': '002',
    29. 'menuName': '饼状图',
    30. 'url': '/charts/charts2',
    31. 'sortNo': 4,
    32. 'icon': 'ArrowDownBold'
    33. },
    34. {
    35. 'id': '003',
    36. 'parentId': '0',
    37. 'menuName': '测试四级1',
    38. 'url': '/dashboard',
    39. 'menuType': 1,
    40. 'sortNo': 2,
    41. 'icon': 'Aim'
    42. },
    43. {
    44. 'id': '0031',
    45. 'parentId': '003',
    46. 'menuName': '测试四级2',
    47. 'url': '/dashboard',
    48. 'menuType': 1,
    49. 'sortNo': 2,
    50. 'icon': 'Aim'
    51. },
    52. {
    53. 'id': '00311',
    54. 'parentId': '0031',
    55. 'menuName': '测试四级3',
    56. 'url': '/dashboard',
    57. 'menuType': 1,
    58. 'sortNo': 2,
    59. 'icon': 'Aim'
    60. },
    61. {
    62. 'id': '003111',
    63. 'parentId': '00311',
    64. 'menuName': '测试四级4',
    65. 'url': '/dashboard',
    66. 'menuType': 1,
    67. 'sortNo': 2,
    68. 'icon': 'Aim'
    69. },
    70. ];

    这里需要将数组转换成树形结构,也附上代码好了(纯手工输出,有bug还望见谅):

    1. /*
    2. * @Author: zzh
    3. * @Date: 2022-03-01 14:39:16
    4. * @LastEditors: zzh
    5. * @LastEditTime: 2022-04-10 17:13:03
    6. * @Description: 数据转换帮助类
    7. * @FilePath: \zh-admin\src\utils\dataConvert.ts
    8. */
    9. import { MenuNode } from '../model/menuNode';
    10. // 由于菜单数据并非一颗树,而是多棵树组成的数据,顾当成由树组成的数组的处理
    11. const convertMenuArrToTree = (array: Array<MenuNode>) => {
    12. const rootMenus = array.filter(x => x.parentId === '0');
    13. const childrenMenus = array.filter(x => x.parentId !== '0');
    14. for (let i = 0; i < rootMenus.length; i++) {
    15. if (childrenMenus.find(x => x.parentId === rootMenus[i].id)) {
    16. rootMenus[i].children = getRootMenuChild(rootMenus[i].id, childrenMenus);
    17. } else {
    18. rootMenus[i].children = [];
    19. }
    20. }
    21. return rootMenus;
    22. };
    23. const getRootMenuChild = (id: string, childrenMenus: Array<MenuNode>): Array<MenuNode> => {
    24. const menus = childrenMenus.filter(x => x.parentId === id);
    25. for (let i = 0; i < menus.length; i++) {
    26. if (childrenMenus.find(x => x.parentId === menus[i].id)) {
    27. menus[i].children = getRootMenuChild(menus[i].id, childrenMenus);
    28. } else {
    29. menus[i].children = [];
    30. }
    31. }
    32. return menus;
    33. };
    34. export {
    35. convertMenuArrToTree,
    36. };

    展示结果:

    af47773eb6924169c74f22b03c8a2adb.png

     

  • 相关阅读:
    微服务系列之服务注册发现 Consul
    论文解读:Rectifying the Shortcut Learning of Background for Few-Shot Learning
    第二章网页前端基础与HTTP协议
    SpringBoot对外接口IP黑白名单的设计与实施
    kubernetes部署jenkins
    Apollo在Java中的使用
    Distributed Systems MIT - Introduction总结
    【Linux篇】之常用命令
    E. 矩阵第k大
    Linux 文件、目录和用户权限管理指南
  • 原文地址:https://blog.csdn.net/iotzzh/article/details/124816845