CEES-manage/src/layouts/default/menu/index.vue

164 lines
4.9 KiB
Vue
Raw Normal View History

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';
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
*/
function handleMenuClick(path: string) {
go(path);
}
/**
* 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>