sub-menu.vue 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <script setup lang="ts">
  2. import type { MenuRecordRaw } from '@vben-core/typings';
  3. import { computed } from 'vue';
  4. import { MenuBadge, MenuItem, SubMenu as SubMenuComp } from './components';
  5. // eslint-disable-next-line import/no-self-import
  6. import SubMenu from './sub-menu.vue';
  7. interface Props {
  8. /**
  9. * 菜单项
  10. */
  11. menu: MenuRecordRaw;
  12. }
  13. defineOptions({
  14. name: 'SubMenuUi',
  15. });
  16. const props = withDefaults(defineProps<Props>(), {});
  17. /**
  18. * 判断是否有子节点,动态渲染 menu-item/sub-menu-item
  19. */
  20. const hasChildren = computed(() => {
  21. const { menu } = props;
  22. return (
  23. Reflect.has(menu, 'children') && !!menu.children && menu.children.length > 0
  24. );
  25. });
  26. </script>
  27. <template>
  28. <MenuItem
  29. v-if="!hasChildren"
  30. :key="menu.path"
  31. :active-icon="menu.activeIcon"
  32. :badge="menu.badge"
  33. :badge-type="menu.badgeType"
  34. :badge-variants="menu.badgeVariants"
  35. :icon="menu.icon"
  36. :path="menu.path"
  37. >
  38. <template #title>
  39. <span>{{ menu.name }}</span>
  40. </template>
  41. </MenuItem>
  42. <SubMenuComp
  43. v-else
  44. :key="`${menu.path}_sub`"
  45. :active-icon="menu.activeIcon"
  46. :icon="menu.icon"
  47. :path="menu.path"
  48. >
  49. <template #content>
  50. <MenuBadge
  51. :badge="menu.badge"
  52. :badge-type="menu.badgeType"
  53. :badge-variants="menu.badgeVariants"
  54. class="right-6"
  55. />
  56. </template>
  57. <template #title>
  58. <span>{{ menu.name }}</span>
  59. </template>
  60. <template v-for="childItem in menu.children || []" :key="childItem.path">
  61. <SubMenu :menu="childItem" />
  62. </template>
  63. </SubMenuComp>
  64. </template>