sub-menu.vue 1.5 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. import SubMenu from './sub-menu.vue';
  6. interface Props {
  7. /**
  8. * 菜单项
  9. */
  10. menu: MenuRecordRaw;
  11. }
  12. defineOptions({
  13. name: 'SubMenuUi',
  14. });
  15. const props = withDefaults(defineProps<Props>(), {});
  16. /**
  17. * 判断是否有子节点,动态渲染 menu-item/sub-menu-item
  18. */
  19. const hasChildren = computed(() => {
  20. const { menu } = props;
  21. return (
  22. Reflect.has(menu, 'children') && !!menu.children && menu.children.length > 0
  23. );
  24. });
  25. </script>
  26. <template>
  27. <MenuItem
  28. v-if="!hasChildren"
  29. :key="menu.path"
  30. :active-icon="menu.activeIcon"
  31. :badge="menu.badge"
  32. :badge-type="menu.badgeType"
  33. :badge-variants="menu.badgeVariants"
  34. :icon="menu.icon"
  35. :path="menu.path"
  36. :query="menu.query"
  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>