SimpleSubMenu.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <MenuItem
  3. :name="item.path"
  4. v-if="!menuHasChildren(item) && getShowMenu"
  5. v-bind="$props"
  6. :class="getLevelClass"
  7. >
  8. <Icon v-if="getIcon" :icon="getIcon" :size="16" />
  9. <div v-if="collapsedShowTitle && getIsCollapseParent" class="mt-1 collapse-title">
  10. {{ getI18nName }}
  11. </div>
  12. <template #title>
  13. <span :class="['ml-2', `${prefixCls}-sub-title`]">
  14. {{ getI18nName }}
  15. </span>
  16. <SimpleMenuTag :item="item" :collapseParent="getIsCollapseParent" />
  17. </template>
  18. </MenuItem>
  19. <SubMenu
  20. :name="item.path"
  21. v-if="menuHasChildren(item) && getShowMenu"
  22. :class="[getLevelClass, theme]"
  23. :collapsedShowTitle="collapsedShowTitle"
  24. >
  25. <template #title>
  26. <Icon v-if="getIcon" :icon="getIcon" :size="16" />
  27. <div v-if="collapsedShowTitle && getIsCollapseParent" class="mt-2 collapse-title">
  28. {{ getI18nName }}
  29. </div>
  30. <span v-show="getShowSubTitle" :class="['ml-2', `${prefixCls}-sub-title`]">
  31. {{ getI18nName }}
  32. </span>
  33. <SimpleMenuTag :item="item" :collapseParent="!!collapse && !!parent" />
  34. </template>
  35. <template
  36. v-for="childrenItem in item.children || []"
  37. :key="childrenItem.paramPath || childrenItem.path"
  38. >
  39. <SimpleSubMenu v-bind="$props" :item="childrenItem" :parent="false" />
  40. </template>
  41. </SubMenu>
  42. </template>
  43. <script lang="ts">
  44. import type { PropType } from 'vue';
  45. import type { Menu } from '/@/router/types';
  46. import { defineComponent, computed } from 'vue';
  47. import { useDesign } from '/@/hooks/web/useDesign';
  48. import Icon from '/@/components/Icon/index';
  49. import MenuItem from './components/MenuItem.vue';
  50. import SubMenu from './components/SubMenuItem.vue';
  51. import { propTypes } from '/@/utils/propTypes';
  52. import { useI18n } from '/@/hooks/web/useI18n';
  53. import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
  54. export default defineComponent({
  55. name: 'SimpleSubMenu',
  56. components: {
  57. SubMenu,
  58. MenuItem,
  59. SimpleMenuTag: createAsyncComponent(() => import('./SimpleMenuTag.vue')),
  60. Icon,
  61. },
  62. props: {
  63. item: {
  64. type: Object as PropType<Menu>,
  65. default: () => ({}),
  66. },
  67. parent: propTypes.bool,
  68. collapsedShowTitle: propTypes.bool,
  69. collapse: propTypes.bool,
  70. theme: propTypes.oneOf(['dark', 'light']),
  71. },
  72. setup(props) {
  73. const { t } = useI18n();
  74. const { prefixCls } = useDesign('simple-menu');
  75. const getShowMenu = computed(() => !props.item?.meta?.hideMenu);
  76. const getIcon = computed(() => props.item?.icon);
  77. const getI18nName = computed(() => t(props.item?.name));
  78. const getShowSubTitle = computed(() => !props.collapse || !props.parent);
  79. const getIsCollapseParent = computed(() => !!props.collapse && !!props.parent);
  80. const getLevelClass = computed(() => {
  81. return [
  82. {
  83. [`${prefixCls}__parent`]: props.parent,
  84. [`${prefixCls}__children`]: !props.parent,
  85. },
  86. ];
  87. });
  88. function menuHasChildren(menuTreeItem: Menu): boolean {
  89. return (
  90. !menuTreeItem.meta?.hideChildrenInMenu &&
  91. Reflect.has(menuTreeItem, 'children') &&
  92. !!menuTreeItem.children &&
  93. menuTreeItem.children.length > 0
  94. );
  95. }
  96. return {
  97. prefixCls,
  98. menuHasChildren,
  99. getShowMenu,
  100. getIcon,
  101. getI18nName,
  102. getShowSubTitle,
  103. getLevelClass,
  104. getIsCollapseParent,
  105. };
  106. },
  107. });
  108. </script>