2021-10-20 14:32:09 +08:00
|
|
|
<script lang="tsx">
|
2022-06-10 10:44:44 +08:00
|
|
|
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';
|
2022-06-21 17:53:49 +08:00
|
|
|
import { useLocaleStore } from '/@/store/modules/locale';
|
2022-06-10 10:44:44 +08:00
|
|
|
|
|
|
|
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: '',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
setup(props) {
|
|
|
|
const go = useGo();
|
|
|
|
|
|
|
|
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 {
|
|
|
|
height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '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
|
|
|
|
*/
|
2022-06-21 17:53:49 +08:00
|
|
|
//update-begin-author:taoyan date:2022-6-1 for: VUEN-1144 online 配置成菜单后,打开菜单,显示名称未展示为菜单名称
|
|
|
|
const localeStore = useLocaleStore();
|
|
|
|
function handleMenuClick(path: string, item) {
|
|
|
|
if (item) {
|
|
|
|
localeStore.setPathTitle(path, item.title || '');
|
|
|
|
}
|
2022-06-10 10:44:44 +08:00
|
|
|
go(path);
|
|
|
|
}
|
2022-06-21 17:53:49 +08:00
|
|
|
//update-end-author:taoyan date:2022-6-1 for: VUEN-1144 online 配置成菜单后,打开菜单,显示名称未展示为菜单名称
|
2022-06-10 10:44:44 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* before click menu
|
|
|
|
* @param menu
|
|
|
|
*/
|
|
|
|
async function beforeMenuClickFn(path: string) {
|
|
|
|
if (!isUrl(path)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
openWindow(path);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderHeader() {
|
|
|
|
if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null;
|
|
|
|
|
|
|
|
return <AppLogo showTitle={!unref(getCollapsed)} class={unref(getLogoClass)} theme={unref(getComputedMenuTheme)} />;
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderMenu() {
|
|
|
|
const { menus, ...menuProps } = unref(getCommonProps);
|
|
|
|
// console.log(menus);
|
|
|
|
if (!menus || !menus.length) return null;
|
|
|
|
return !props.isHorizontal ? (
|
|
|
|
<SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} />
|
|
|
|
) : (
|
|
|
|
<BasicMenu {...(menuProps as any)} isHorizontal={props.isHorizontal} type={unref(getMenuType)} showLogo={unref(getIsShowLogo)} mode={unref(getComputedMenuMode as any)} items={menus} />
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{renderHeader()}
|
|
|
|
{unref(getUseScroll) ? <ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer> : renderMenu()}
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
},
|
|
|
|
});
|
2021-10-20 14:32:09 +08:00
|
|
|
</script>
|
|
|
|
<style lang="less">
|
2022-06-10 10:44:44 +08:00
|
|
|
@prefix-cls: ~'@{namespace}-layout-menu';
|
|
|
|
@logo-prefix-cls: ~'@{namespace}-app-logo';
|
|
|
|
|
|
|
|
.@{prefix-cls} {
|
|
|
|
&-logo {
|
|
|
|
height: @header-height;
|
|
|
|
padding: 10px 4px 10px 10px;
|
|
|
|
|
|
|
|
img {
|
|
|
|
width: @logo-width;
|
|
|
|
height: @logo-width;
|
|
|
|
}
|
|
|
|
}
|
2021-10-20 14:32:09 +08:00
|
|
|
|
2022-06-10 10:44:44 +08:00
|
|
|
&--mobile {
|
|
|
|
.@{logo-prefix-cls} {
|
|
|
|
&__title {
|
|
|
|
opacity: 1;
|
2021-10-20 14:32:09 +08:00
|
|
|
}
|
2022-06-10 10:44:44 +08:00
|
|
|
}
|
2021-10-20 14:32:09 +08:00
|
|
|
}
|
2022-06-10 10:44:44 +08:00
|
|
|
}
|
2021-10-20 14:32:09 +08:00
|
|
|
</style>
|