sub-menu.vue 1.6 KB

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