index.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <script lang="tsx">
  2. import type { PropType, CSSProperties } from 'vue';
  3. import { computed, defineComponent, unref, toRef } from 'vue';
  4. import { BasicMenu } from '/@/components/Menu';
  5. import { SimpleMenu } from '/@/components/SimpleMenu';
  6. import { AppLogo } from '/@/components/Application';
  7. import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
  8. import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  9. import { ScrollContainer } from '/@/components/Container';
  10. import { useGo } from '/@/hooks/web/usePage';
  11. import { useSplitMenu } from './useLayoutMenu';
  12. import { openWindow } from '/@/utils';
  13. import { propTypes } from '/@/utils/propTypes';
  14. import { isUrl } from '/@/utils/is';
  15. import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  16. import { useAppInject } from '/@/hooks/web/useAppInject';
  17. import { useDesign } from '/@/hooks/web/useDesign';
  18. import { useLocaleStore } from '/@/store/modules/locale';
  19. export default defineComponent({
  20. name: 'LayoutMenu',
  21. props: {
  22. theme: propTypes.oneOf(['light', 'dark']),
  23. splitType: {
  24. type: Number as PropType<MenuSplitTyeEnum>,
  25. default: MenuSplitTyeEnum.NONE,
  26. },
  27. isHorizontal: propTypes.bool,
  28. // menu Mode
  29. menuMode: {
  30. type: [String] as PropType<Nullable<MenuModeEnum>>,
  31. default: '',
  32. },
  33. },
  34. setup(props) {
  35. const go = useGo();
  36. const {
  37. getMenuMode,
  38. getMenuType,
  39. getMenuTheme,
  40. getCollapsed,
  41. getCollapsedShowTitle,
  42. getAccordion,
  43. getIsHorizontal,
  44. getIsSidebarType,
  45. getSplit,
  46. } = useMenuSetting();
  47. const { getShowLogo } = useRootSetting();
  48. const { prefixCls } = useDesign('layout-menu');
  49. const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
  50. const { getIsMobile } = useAppInject();
  51. const getComputedMenuMode = computed(() => (unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)));
  52. const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
  53. const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
  54. const getUseScroll = computed(() => {
  55. return (
  56. !unref(getIsHorizontal) &&
  57. (unref(getIsSidebarType) || props.splitType === MenuSplitTyeEnum.LEFT || props.splitType === MenuSplitTyeEnum.NONE)
  58. );
  59. });
  60. const getWrapperStyle = computed((): CSSProperties => {
  61. return {
  62. height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`,
  63. };
  64. });
  65. const getLogoClass = computed(() => {
  66. return [
  67. `${prefixCls}-logo`,
  68. unref(getComputedMenuTheme),
  69. {
  70. [`${prefixCls}--mobile`]: unref(getIsMobile),
  71. },
  72. ];
  73. });
  74. const getCommonProps = computed(() => {
  75. const menus = unref(menusRef);
  76. return {
  77. menus,
  78. beforeClickFn: beforeMenuClickFn,
  79. items: menus,
  80. theme: unref(getComputedMenuTheme),
  81. accordion: unref(getAccordion),
  82. collapse: unref(getCollapsed),
  83. collapsedShowTitle: unref(getCollapsedShowTitle),
  84. onMenuClick: handleMenuClick,
  85. };
  86. });
  87. /**
  88. * click menu
  89. * @param menu
  90. */
  91. //update-begin-author:taoyan date:2022-6-1 for: VUEN-1144 online 配置成菜单后,打开菜单,显示名称未展示为菜单名称
  92. const localeStore = useLocaleStore();
  93. function handleMenuClick(path: string, item) {
  94. debugger
  95. if (item) {
  96. localeStore.setPathTitle(path, item.title || '');
  97. }
  98. go(path);
  99. }
  100. //update-end-author:taoyan date:2022-6-1 for: VUEN-1144 online 配置成菜单后,打开菜单,显示名称未展示为菜单名称
  101. /**
  102. * before click menu
  103. * @param menu
  104. */
  105. async function beforeMenuClickFn(path: string) {
  106. if (!isUrl(path)) {
  107. return true;
  108. }
  109. openWindow(path);
  110. return false;
  111. }
  112. function renderHeader() {
  113. if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null;
  114. return <AppLogo showTitle={!unref(getCollapsed)} class={unref(getLogoClass)} theme={unref(getComputedMenuTheme)} />;
  115. }
  116. function renderMenu() {
  117. const { menus, ...menuProps } = unref(getCommonProps);
  118. // console.log(menus);
  119. if (!menus || !menus.length) return null;
  120. return !props.isHorizontal ? (
  121. <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} />
  122. ) : (
  123. <BasicMenu
  124. {...(menuProps as any)}
  125. isHorizontal={props.isHorizontal}
  126. type={unref(getMenuType)}
  127. showLogo={unref(getIsShowLogo)}
  128. mode={unref(getComputedMenuMode as any)}
  129. items={menus}
  130. />
  131. );
  132. }
  133. return () => {
  134. return (
  135. <>
  136. {renderHeader()}
  137. {unref(getUseScroll) ? <ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer> : renderMenu()}
  138. </>
  139. );
  140. };
  141. },
  142. });
  143. </script>
  144. <style lang="less">
  145. @prefix-cls: ~'@{namespace}-layout-menu';
  146. @logo-prefix-cls: ~'@{namespace}-app-logo';
  147. .@{prefix-cls} {
  148. &-logo {
  149. height: @header-height;
  150. padding: 10px 4px 10px 10px;
  151. img {
  152. width: @logo-width;
  153. height: @logo-width;
  154. }
  155. }
  156. &--mobile {
  157. .@{logo-prefix-cls} {
  158. &__title {
  159. opacity: 1;
  160. }
  161. }
  162. }
  163. }
  164. </style>