|
|
@@ -1,207 +1,209 @@
|
|
|
<script lang="tsx">
|
|
|
- import type { PropType, CSSProperties } from 'vue';
|
|
|
-
|
|
|
- import { computed, defineComponent, unref, toRef } from 'vue';
|
|
|
- import { BasicMenu } from '/@/components/Menu';
|
|
|
- import { SimpleMenu } from '/@/components/SimpleMenu';
|
|
|
- // import { AppLogo } from '/@/components/Application';
|
|
|
-
|
|
|
- import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
|
|
-
|
|
|
- import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
|
|
- import { ScrollContainer } from '/@/components/Container';
|
|
|
-
|
|
|
- import { useGo } from '/@/hooks/web/usePage';
|
|
|
- import { useSplitMenu } from './useLayoutMenu';
|
|
|
- import { openWindow } from '/@/utils';
|
|
|
- import { propTypes } from '/@/utils/propTypes';
|
|
|
- import { isUrl } from '/@/utils/is';
|
|
|
- import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
|
|
- import { useAppInject } from '/@/hooks/web/useAppInject';
|
|
|
- // import { useDesign } from '/@/hooks/web/useDesign';
|
|
|
- import { useLocaleStore } from '/@/store/modules/locale';
|
|
|
- import { Button } from 'ant-design-vue';
|
|
|
- import { SearchOutlined } from '@ant-design/icons-vue';
|
|
|
- import { useI18n } from '/@/hooks/web/useI18n';
|
|
|
- import { AppSearch } from '/@/components/Application';
|
|
|
-
|
|
|
- export default defineComponent({
|
|
|
- name: 'LayoutMenu',
|
|
|
- props: {
|
|
|
- theme: propTypes.oneOf(['light', 'dark']),
|
|
|
-
|
|
|
- splitType: {
|
|
|
- type: Number as PropType<MenuSplitTyeEnum>,
|
|
|
- default: MenuSplitTyeEnum.NONE,
|
|
|
- },
|
|
|
-
|
|
|
- isHorizontal: propTypes.bool,
|
|
|
- // menu Mode
|
|
|
- menuMode: {
|
|
|
- type: [String] as PropType<Nullable<MenuModeEnum>>,
|
|
|
- default: '',
|
|
|
- },
|
|
|
+import type { PropType, CSSProperties } from 'vue';
|
|
|
+
|
|
|
+import { computed, defineComponent, unref, toRef } from 'vue';
|
|
|
+import { BasicMenu } from '/@/components/Menu';
|
|
|
+import { SimpleMenu } from '/@/components/SimpleMenu';
|
|
|
+// import { AppLogo } from '/@/components/Application';
|
|
|
+
|
|
|
+import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
|
|
+
|
|
|
+import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
|
|
+import { ScrollContainer } from '/@/components/Container';
|
|
|
+
|
|
|
+import { useGo } from '/@/hooks/web/usePage';
|
|
|
+import { useSplitMenu } from './useLayoutMenu';
|
|
|
+import { openWindow } from '/@/utils';
|
|
|
+import { propTypes } from '/@/utils/propTypes';
|
|
|
+import { isUrl } from '/@/utils/is';
|
|
|
+import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
|
|
+import { useAppInject } from '/@/hooks/web/useAppInject';
|
|
|
+// import { useDesign } from '/@/hooks/web/useDesign';
|
|
|
+import { useLocaleStore } from '/@/store/modules/locale';
|
|
|
+import { Button } from 'ant-design-vue';
|
|
|
+import { SearchOutlined } from '@ant-design/icons-vue';
|
|
|
+import { useI18n } from '/@/hooks/web/useI18n';
|
|
|
+import { AppSearch } from '/@/components/Application';
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'LayoutMenu',
|
|
|
+ props: {
|
|
|
+ theme: propTypes.oneOf(['light', 'dark']),
|
|
|
+
|
|
|
+ splitType: {
|
|
|
+ type: Number as PropType<MenuSplitTyeEnum>,
|
|
|
+ default: MenuSplitTyeEnum.NONE,
|
|
|
},
|
|
|
- setup(props) {
|
|
|
- const go = useGo();
|
|
|
- const { t } = useI18n();
|
|
|
-
|
|
|
- const {
|
|
|
- getMenuMode,
|
|
|
- getMenuType,
|
|
|
- getMenuTheme,
|
|
|
- getCollapsed,
|
|
|
- getCollapsedShowTitle,
|
|
|
- getAccordion,
|
|
|
- getIsHorizontal,
|
|
|
- getIsSidebarType,
|
|
|
- getSplit,
|
|
|
- } = useMenuSetting();
|
|
|
- const { getShowLogo } = useRootSetting();
|
|
|
-
|
|
|
- // const { prefixCls } = useDesign('layout-menu');
|
|
|
-
|
|
|
- const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
|
|
|
-
|
|
|
- const { getIsMobile } = useAppInject();
|
|
|
-
|
|
|
- const getComputedMenuMode = computed(() => (unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)));
|
|
|
-
|
|
|
- const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
|
|
|
-
|
|
|
- const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
|
|
|
-
|
|
|
- const getUseScroll = computed(() => {
|
|
|
- return (
|
|
|
- !unref(getIsHorizontal) &&
|
|
|
- (unref(getIsSidebarType) || props.splitType === MenuSplitTyeEnum.LEFT || props.splitType === MenuSplitTyeEnum.NONE)
|
|
|
- );
|
|
|
- });
|
|
|
-
|
|
|
- const getWrapperStyle = computed((): CSSProperties => {
|
|
|
- return {
|
|
|
- // 代码逻辑说明: 【issues/7548】侧边栏导航模式时会导致下面菜单滚动显示不全
|
|
|
- height: `calc(100% - ${unref(getIsShowLogo) ? '60px' : '0px'})`,
|
|
|
- };
|
|
|
- });
|
|
|
-
|
|
|
- // const getLogoClass = computed(() => {
|
|
|
- // return [
|
|
|
- // `${prefixCls}-logo`,
|
|
|
- // unref(getComputedMenuTheme),
|
|
|
- // {
|
|
|
- // [`${prefixCls}--mobile`]: unref(getIsMobile),
|
|
|
- // },
|
|
|
- // ];
|
|
|
- // });
|
|
|
-
|
|
|
- const getCommonProps = computed(() => {
|
|
|
- const menus = unref(menusRef);
|
|
|
- return {
|
|
|
- menus,
|
|
|
- beforeClickFn: beforeMenuClickFn,
|
|
|
- items: menus,
|
|
|
- theme: unref(getComputedMenuTheme),
|
|
|
- accordion: unref(getAccordion),
|
|
|
- collapse: unref(getCollapsed),
|
|
|
- collapsedShowTitle: unref(getCollapsedShowTitle),
|
|
|
- onMenuClick: handleMenuClick,
|
|
|
- };
|
|
|
- });
|
|
|
- /**
|
|
|
- * click menu
|
|
|
- * @param menu
|
|
|
- */
|
|
|
- // 代码逻辑说明: VUEN-1144 online 配置成菜单后,打开菜单,显示名称未展示为菜单名称
|
|
|
- const localeStore = useLocaleStore();
|
|
|
- function handleMenuClick(path: string, item) {
|
|
|
- if (item) {
|
|
|
- localeStore.setPathTitle(path, item.title || '');
|
|
|
- }
|
|
|
- go(path);
|
|
|
- }
|
|
|
|
|
|
- /**
|
|
|
- * before click menu
|
|
|
- * @param menu
|
|
|
- */
|
|
|
- async function beforeMenuClickFn(path: string) {
|
|
|
- if (!isUrl(path)) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- openWindow(path);
|
|
|
- return false;
|
|
|
+ isHorizontal: propTypes.bool,
|
|
|
+ // menu Mode
|
|
|
+ menuMode: {
|
|
|
+ type: [String] as PropType<Nullable<MenuModeEnum>>,
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ setup(props) {
|
|
|
+ const go = useGo();
|
|
|
+ const { t } = useI18n();
|
|
|
+
|
|
|
+ const {
|
|
|
+ getMenuMode,
|
|
|
+ getMenuType,
|
|
|
+ getMenuTheme,
|
|
|
+ getCollapsed,
|
|
|
+ getCollapsedShowTitle,
|
|
|
+ getAccordion,
|
|
|
+ getIsHorizontal,
|
|
|
+ getIsSidebarType,
|
|
|
+ getSplit,
|
|
|
+ } = useMenuSetting();
|
|
|
+ const { getShowLogo } = useRootSetting();
|
|
|
+
|
|
|
+ // const { prefixCls } = useDesign('layout-menu');
|
|
|
+
|
|
|
+ const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
|
|
|
+
|
|
|
+ const { getIsMobile } = useAppInject();
|
|
|
+
|
|
|
+ const getComputedMenuMode = computed(() => (unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)));
|
|
|
+
|
|
|
+ const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
|
|
|
+
|
|
|
+ const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
|
|
|
+
|
|
|
+ const getUseScroll = computed(() => {
|
|
|
+ return (
|
|
|
+ !unref(getIsHorizontal) &&
|
|
|
+ (unref(getIsSidebarType) || props.splitType === MenuSplitTyeEnum.LEFT || props.splitType === MenuSplitTyeEnum.NONE)
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ const getWrapperStyle = computed((): CSSProperties => {
|
|
|
+ return {
|
|
|
+ // 代码逻辑说明: 【issues/7548】侧边栏导航模式时会导致下面菜单滚动显示不全
|
|
|
+ height: `calc(100% - ${unref(getIsShowLogo) ? '60px' : '0px'})`,
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ // const getLogoClass = computed(() => {
|
|
|
+ // return [
|
|
|
+ // `${prefixCls}-logo`,
|
|
|
+ // unref(getComputedMenuTheme),
|
|
|
+ // {
|
|
|
+ // [`${prefixCls}--mobile`]: unref(getIsMobile),
|
|
|
+ // },
|
|
|
+ // ];
|
|
|
+ // });
|
|
|
+
|
|
|
+ const getCommonProps = computed(() => {
|
|
|
+ const menus = unref(menusRef);
|
|
|
+ return {
|
|
|
+ menus,
|
|
|
+ beforeClickFn: beforeMenuClickFn,
|
|
|
+ items: menus,
|
|
|
+ theme: unref(getComputedMenuTheme),
|
|
|
+ accordion: unref(getAccordion),
|
|
|
+ collapse: unref(getCollapsed),
|
|
|
+ collapsedShowTitle: unref(getCollapsedShowTitle),
|
|
|
+ onMenuClick: handleMenuClick,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ /**
|
|
|
+ * click menu
|
|
|
+ * @param menu
|
|
|
+ */
|
|
|
+ // 代码逻辑说明: VUEN-1144 online 配置成菜单后,打开菜单,显示名称未展示为菜单名称
|
|
|
+ const localeStore = useLocaleStore();
|
|
|
+ function handleMenuClick(path: string, item) {
|
|
|
+ if (item) {
|
|
|
+ localeStore.setPathTitle(path, item.title || '');
|
|
|
}
|
|
|
+ go(path);
|
|
|
+ }
|
|
|
|
|
|
- function renderMenu() {
|
|
|
- const { menus, ...menuProps } = unref(getCommonProps);
|
|
|
- // console.log(menus);
|
|
|
- if (!menus || !menus.length) return null;
|
|
|
- return (
|
|
|
- <>
|
|
|
- {!getCollapsed.value ? (
|
|
|
- <AppSearch class="m-5px">
|
|
|
- <Button class="w-full">
|
|
|
- {t('layout.setting.menuSearch')}
|
|
|
- <SearchOutlined />
|
|
|
- </Button>
|
|
|
- </AppSearch>
|
|
|
- ) : (
|
|
|
- <AppSearch class="m-5px">
|
|
|
- <Button shape="circle">
|
|
|
- <SearchOutlined />
|
|
|
- </Button>
|
|
|
- </AppSearch>
|
|
|
- )}
|
|
|
- {!props.isHorizontal ? (
|
|
|
- <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menusRef.value} />
|
|
|
- ) : (
|
|
|
- <BasicMenu
|
|
|
- {...(menuProps as any)}
|
|
|
- isHorizontal={props.isHorizontal}
|
|
|
- type={unref(getMenuType)}
|
|
|
- showLogo={unref(getIsShowLogo)}
|
|
|
- mode={unref(getComputedMenuMode as any)}
|
|
|
- items={menusRef.value}
|
|
|
- />
|
|
|
- )}
|
|
|
- </>
|
|
|
- );
|
|
|
+ /**
|
|
|
+ * before click menu
|
|
|
+ * @param menu
|
|
|
+ */
|
|
|
+ async function beforeMenuClickFn(path: string) {
|
|
|
+ if (!isUrl(path)) {
|
|
|
+ return true;
|
|
|
}
|
|
|
+ openWindow(path);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- return () => {
|
|
|
- return <>{unref(getUseScroll) ? <ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer> : renderMenu()}</>;
|
|
|
- };
|
|
|
- },
|
|
|
- });
|
|
|
+ function renderMenu() {
|
|
|
+ const { menus, ...menuProps } = unref(getCommonProps);
|
|
|
+ // console.log(menus);
|
|
|
+ if (!menus || !menus.length) return null;
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ {!getCollapsed.value ? (
|
|
|
+ <AppSearch class="m-5px">
|
|
|
+ <Button class="w-full">
|
|
|
+ {t('layout.setting.menuSearch')}
|
|
|
+ <SearchOutlined />
|
|
|
+ </Button>
|
|
|
+ </AppSearch>
|
|
|
+ ) : (
|
|
|
+ <AppSearch class="m-5px">
|
|
|
+ <Button shape="circle">
|
|
|
+ <SearchOutlined />
|
|
|
+ </Button>
|
|
|
+ </AppSearch>
|
|
|
+ )}
|
|
|
+ {!props.isHorizontal ? (
|
|
|
+ <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menusRef.value} />
|
|
|
+ ) : (
|
|
|
+ <BasicMenu
|
|
|
+ {...(menuProps as any)}
|
|
|
+ isHorizontal={props.isHorizontal}
|
|
|
+ type={unref(getMenuType)}
|
|
|
+ showLogo={unref(getIsShowLogo)}
|
|
|
+ mode={unref(getComputedMenuMode as any)}
|
|
|
+ items={menusRef.value}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </>
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ return <>{unref(getUseScroll) ? <ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer> : renderMenu()}</>;
|
|
|
+ };
|
|
|
+ },
|
|
|
+});
|
|
|
</script>
|
|
|
<style lang="less" scoped>
|
|
|
- // 代码逻辑说明: 【QQYUN-5872】菜单优化,上下滚动条去掉
|
|
|
- .scroll-container :deep(.scrollbar__bar) {
|
|
|
- display: none;
|
|
|
- }
|
|
|
+// 代码逻辑说明: 【QQYUN-5872】菜单优化,上下滚动条去掉
|
|
|
+.scroll-container :deep(.scrollbar__bar) {
|
|
|
+ display: none;
|
|
|
+}
|
|
|
</style>
|
|
|
<style lang="less">
|
|
|
- @prefix-cls: ~'@{namespace}-layout-menu';
|
|
|
- @logo-prefix-cls: ~'@{namespace}-app-logo';
|
|
|
+@prefix-cls: ~'@{namespace}-layout-menu';
|
|
|
+@logo-prefix-cls: ~'@{namespace}-app-logo';
|
|
|
|
|
|
- .@{prefix-cls} {
|
|
|
- &-logo {
|
|
|
- height: @header-height;
|
|
|
- padding: 10px 4px 10px 10px;
|
|
|
+.@{prefix-cls} {
|
|
|
+ &-logo {
|
|
|
+ height: @header-height;
|
|
|
+ padding: 10px 4px 10px 10px;
|
|
|
|
|
|
- img {
|
|
|
- width: @logo-width;
|
|
|
- height: @logo-width;
|
|
|
- }
|
|
|
+ img {
|
|
|
+ width: @logo-width;
|
|
|
+ height: @logo-width;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- &--mobile {
|
|
|
- .@{logo-prefix-cls} {
|
|
|
- &__title {
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
+ &--mobile {
|
|
|
+ .@{logo-prefix-cls} {
|
|
|
+ &__title {
|
|
|
+ opacity: 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
</style>
|