index.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import './index.less';
  2. import type { PropType, CSSProperties } from 'vue';
  3. import { computed, defineComponent, unref, toRef } from 'vue';
  4. import { BasicMenu } from '/@/components/Menu';
  5. import { AppLogo } from '/@/components/Application';
  6. import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
  7. import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  8. import { ScrollContainer } from '/@/components/Container';
  9. import { useGo } from '/@/hooks/web/usePage';
  10. import { useSplitMenu } from './useLayoutMenu';
  11. import { openWindow } from '/@/utils';
  12. import { propTypes } from '/@/utils/propTypes';
  13. import { isUrl } from '/@/utils/is';
  14. import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  15. import { useAppInject } from '/@/hooks/web/useAppInject';
  16. import { useDesign } from '/@/hooks/web/useDesign';
  17. export default defineComponent({
  18. name: 'LayoutMenu',
  19. props: {
  20. theme: propTypes.oneOf(['light', 'dark']),
  21. splitType: {
  22. type: Number as PropType<MenuSplitTyeEnum>,
  23. default: MenuSplitTyeEnum.NONE,
  24. },
  25. isHorizontal: propTypes.bool,
  26. // menu Mode
  27. menuMode: {
  28. type: [String] as PropType<Nullable<MenuModeEnum>>,
  29. default: '',
  30. },
  31. },
  32. setup(props) {
  33. const go = useGo();
  34. const {
  35. getMenuMode,
  36. getMenuType,
  37. getMenuTheme,
  38. getCollapsed,
  39. getCollapsedShowTitle,
  40. getAccordion,
  41. getIsHorizontal,
  42. getIsSidebarType,
  43. } = useMenuSetting();
  44. const { getShowLogo } = useRootSetting();
  45. const { prefixCls } = useDesign('layout-menu');
  46. const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
  47. const { getIsMobile } = useAppInject();
  48. const getComputedMenuMode = computed(() =>
  49. unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)
  50. );
  51. const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
  52. const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
  53. const getUseScroll = computed(() => {
  54. return (
  55. !unref(getIsHorizontal) &&
  56. (unref(getIsSidebarType) ||
  57. props.splitType === MenuSplitTyeEnum.LEFT ||
  58. props.splitType === MenuSplitTyeEnum.NONE)
  59. );
  60. });
  61. const getWrapperStyle = computed(
  62. (): CSSProperties => {
  63. return {
  64. height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`,
  65. };
  66. }
  67. );
  68. const getLogoClass = computed(() => {
  69. return [
  70. `${prefixCls}-logo`,
  71. unref(getComputedMenuTheme),
  72. {
  73. [`${prefixCls}--mobile`]: unref(getIsMobile),
  74. },
  75. ];
  76. });
  77. /**
  78. * click menu
  79. * @param menu
  80. */
  81. function handleMenuClick(path: string) {
  82. go(path);
  83. }
  84. /**
  85. * before click menu
  86. * @param menu
  87. */
  88. async function beforeMenuClickFn(path: string) {
  89. if (!isUrl(path)) {
  90. return true;
  91. }
  92. openWindow(path);
  93. return false;
  94. }
  95. function renderHeader() {
  96. if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null;
  97. return (
  98. <AppLogo
  99. showTitle={!unref(getCollapsed)}
  100. class={unref(getLogoClass)}
  101. theme={unref(getComputedMenuTheme)}
  102. />
  103. );
  104. }
  105. function renderMenu() {
  106. return (
  107. <BasicMenu
  108. beforeClickFn={beforeMenuClickFn}
  109. isHorizontal={props.isHorizontal}
  110. type={unref(getMenuType)}
  111. collapsedShowTitle={unref(getCollapsedShowTitle)}
  112. showLogo={unref(getIsShowLogo)}
  113. mode={unref(getComputedMenuMode)}
  114. theme={unref(getComputedMenuTheme)}
  115. items={unref(menusRef)}
  116. accordion={unref(getAccordion)}
  117. onMenuClick={handleMenuClick}
  118. />
  119. );
  120. }
  121. return () => {
  122. return (
  123. <>
  124. {renderHeader()}
  125. {unref(getUseScroll) ? (
  126. <ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer>
  127. ) : (
  128. renderMenu()
  129. )}
  130. </>
  131. );
  132. };
  133. },
  134. });