index.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import './index.less';
  2. import { PropType, toRef } from 'vue';
  3. import type { Menu } from '/@/router/types';
  4. import { computed, defineComponent, unref } from 'vue';
  5. import { BasicMenu } from '/@/components/Menu/index';
  6. import { AppLogo } from '/@/components/Application';
  7. import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
  8. import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  9. import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  10. import { useGo } from '/@/hooks/web/usePage';
  11. import { useSplitMenu } from './useLayoutMenu';
  12. import { openWindow } from '/@/utils';
  13. import { propTypes } from '/@/utils/propTypes';
  14. export default defineComponent({
  15. name: 'LayoutMenu',
  16. props: {
  17. theme: propTypes.oneOf(['light', 'dark']),
  18. splitType: {
  19. type: Number as PropType<MenuSplitTyeEnum>,
  20. default: MenuSplitTyeEnum.NONE,
  21. },
  22. isHorizontal: propTypes.bool,
  23. // menu Mode
  24. menuMode: {
  25. type: [String] as PropType<Nullable<MenuModeEnum>>,
  26. default: '',
  27. },
  28. },
  29. setup(props) {
  30. const go = useGo();
  31. const {
  32. setMenuSetting,
  33. getMenuMode,
  34. getMenuType,
  35. getCollapsedShowTitle,
  36. getIsSidebarType,
  37. getMenuTheme,
  38. getCollapsed,
  39. getAccordion,
  40. } = useMenuSetting();
  41. const { getShowLogo } = useRootSetting();
  42. const { flatMenusRef, menusRef } = useSplitMenu(toRef(props, 'splitType'));
  43. const showLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
  44. const getComputedMenuMode = computed(() => props.menuMode || unref(getMenuMode));
  45. const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
  46. const appendClass = computed(() => props.splitType === MenuSplitTyeEnum.TOP);
  47. /**
  48. * click menu
  49. * @param menu
  50. */
  51. function handleMenuClick(menu: Menu) {
  52. go(menu.path);
  53. }
  54. /**
  55. * before click menu
  56. * @param menu
  57. */
  58. async function beforeMenuClickFn(menu: Menu) {
  59. const { meta: { externalLink } = {} } = menu;
  60. if (externalLink) {
  61. openWindow(externalLink);
  62. return false;
  63. }
  64. return true;
  65. }
  66. function handleClickSearchInput() {
  67. unref(getCollapsed) && setMenuSetting({ collapsed: false });
  68. }
  69. function renderHeader() {
  70. if (!unref(showLogo)) return null;
  71. return (
  72. <AppLogo
  73. showTitle={!unref(getCollapsed)}
  74. class={[`layout-menu__logo`, unref(getComputedMenuTheme)]}
  75. theme={unref(getComputedMenuTheme)}
  76. />
  77. );
  78. }
  79. return () => {
  80. return (
  81. <BasicMenu
  82. class="layout-menu"
  83. beforeClickFn={beforeMenuClickFn}
  84. isHorizontal={props.isHorizontal}
  85. appendClass={unref(appendClass)}
  86. type={unref(getMenuType)}
  87. mode={unref(getComputedMenuMode)}
  88. collapsedShowTitle={unref(getCollapsedShowTitle)}
  89. theme={unref(getComputedMenuTheme)}
  90. showLogo={unref(showLogo)}
  91. items={unref(menusRef)}
  92. flatItems={unref(flatMenusRef)}
  93. accordion={unref(getAccordion)}
  94. onMenuClick={handleMenuClick}
  95. onClickSearchInput={handleClickSearchInput}
  96. >
  97. {{
  98. header: () => renderHeader(),
  99. }}
  100. </BasicMenu>
  101. );
  102. };
  103. },
  104. });