wip(menu): perf menu

This commit is contained in:
vben
2020-12-15 00:13:23 +08:00
parent ec7efcf0f0
commit a65ad9edd5
80 changed files with 1338 additions and 972 deletions

View File

@@ -3,38 +3,19 @@ import './index.less';
import type { FunctionalComponent } from 'vue';
import type { Component } from '/@/components/types';
import {
defineComponent,
unref,
computed,
ref,
nextTick,
watchEffect,
// nextTick
} from 'vue';
import { defineComponent, unref, computed } from 'vue';
import { Layout, Tooltip, Badge } from 'ant-design-vue';
import { AppLogo } from '/@/components/Application';
import UserDropdown from './UserDropdown';
import LayoutMenu from '../menu';
import LayoutBreadcrumb from './LayoutBreadcrumb.vue';
import LockAction from './actions/LockAction';
import LayoutTrigger from '../trigger/index.vue';
import NoticeAction from './notice/NoticeActionItem.vue';
import {
RedoOutlined,
FullscreenExitOutlined,
FullscreenOutlined,
LockOutlined,
BugOutlined,
} from '@ant-design/icons-vue';
import { LockOutlined, BugOutlined } from '@ant-design/icons-vue';
import { AppSearch } from '/@/components/Application';
import { useModal } from '/@/components/Modal';
import { useFullscreen } from '/@/hooks/web/useFullScreen';
import { useTabs } from '/@/hooks/web/useTabs';
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
@@ -49,8 +30,10 @@ import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { AppLocalePicker } from '/@/components/Application';
import { useI18n } from '/@/hooks/web/useI18n';
import { propTypes } from '/@/utils/propTypes';
import { useLayoutContext } from '../useLayoutContext';
import { UserDropDown, LayoutBreadcrumb, FullScreen } from './components';
import { useAppInject } from '/@/hooks/web/useAppInject';
import { useDesign } from '../../../hooks/web/useDesign';
interface TooltipItemProps {
title: string;
}
@@ -72,24 +55,14 @@ export default defineComponent({
fixed: propTypes.bool,
},
setup(props) {
let logoEl: Element | null | undefined;
const logoWidthRef = ref(200);
const logoRef = ref<ComponentRef>(null);
const injectValue = useLayoutContext();
const { refreshPage } = useTabs();
const { t } = useI18n();
const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsHorizontal } = useMenuSetting();
const { prefixCls } = useDesign('layout-header');
const { getShowTopMenu, getShowHeaderTrigger, getSplit } = useMenuSetting();
const { getShowLocale } = useLocaleSetting();
const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting();
const { getUseErrorHandle } = useRootSetting();
const {
getHeaderTheme,
getShowRedo,
getUseLockPage,
getShowFullScreen,
getShowNotice,
@@ -100,23 +73,11 @@ export default defineComponent({
const { push } = useRouter();
const [register, { openModal }] = useModal();
const { toggleFullscreen, isFullscreenRef } = useFullscreen();
useWindowSizeFn(
() => {
calcTopMenuWidth();
},
100,
{ immediate: false }
);
const { getIsMobile } = useAppInject();
const headerClass = computed(() => {
const theme = unref(getHeaderTheme);
return theme ? `layout-header__header--${theme}` : '';
});
const isPc = computed(() => {
return !unref(injectValue.isMobile);
return theme ? `${prefixCls}__header--${theme}` : '';
});
const getSplitType = computed(() => {
@@ -127,25 +88,6 @@ export default defineComponent({
return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
});
watchEffect(() => {
if (unref(getIsHorizontal)) {
calcTopMenuWidth();
}
});
function calcTopMenuWidth() {
nextTick(() => {
if (!unref(getShowTopMenu)) return;
let width = 0;
if (!logoEl) {
logoEl = unref(logoRef)?.$el;
}
if (!logoEl) return;
width += logoEl.clientWidth;
logoWidthRef.value = width + 80;
});
}
function handleToErrorList() {
push(PageEnum.ERROR_LOG_PAGE).then(() => {
errorStore.commitErrorListCountState(0);
@@ -156,27 +98,28 @@ export default defineComponent({
openModal(true);
}
function renderHeaderContent() {
const width = unref(logoWidthRef);
function renderHeaderLeft() {
return (
<div class="layout-header__content ">
{unref(getShowHeaderLogo) && (
<AppLogo class={`layout-header__logo`} ref={logoRef} theme={unref(getHeaderTheme)} />
)}
<>
{unref(getShowContent) && (
<div class="layout-header__left">
<div class={`${prefixCls}__left`}>
{unref(getShowHeaderTrigger) && (
<LayoutTrigger theme={unref(getHeaderTheme)} sider={false} />
)}
{unref(getShowBread) && unref(isPc) && (
<LayoutBreadcrumb showIcon={unref(getShowBreadCrumbIcon)} />
{unref(getShowBread) && !unref(getIsMobile) && (
<LayoutBreadcrumb theme={unref(getHeaderTheme)} />
)}
</div>
)}
</>
);
}
{unref(getShowTopMenu) && unref(isPc) && (
<div class={[`layout-header__menu `]} style={{ width: `calc(100% - ${width}px)` }}>
function renderHeaderContent() {
return (
<div class={`${prefixCls}__content`}>
{unref(getShowTopMenu) && !unref(getIsMobile) && (
<div class={[`${prefixCls}__menu `]}>
{/* <div class={[`layout-header__menu `]}> */}
<LayoutMenu
isHorizontal={true}
@@ -193,18 +136,18 @@ export default defineComponent({
function renderActionDefault(Comp: Component | any, event: Fn) {
return (
<div class="layout-header__action-item" onClick={event}>
<Comp class="layout-header__action-icon" />
<div class={`${prefixCls}__action-item`} onClick={event}>
<Comp class={`${prefixCls}__action-icon`} />
</div>
);
}
function renderAction() {
return (
<div class={`layout-header__action`}>
{unref(isPc) && <AppSearch class="layout-header__action-item" />}
<div class={`${prefixCls}__action`}>
{!unref(getIsMobile) && <AppSearch class={`${prefixCls}__action-item`} />}
{unref(getUseErrorHandle) && unref(isPc) && (
{unref(getUseErrorHandle) && !unref(getIsMobile) && (
<TooltipItem title={t('layout.header.tooltipErrorLog')}>
{() => (
<Badge
@@ -219,48 +162,27 @@ export default defineComponent({
</TooltipItem>
)}
{unref(getUseLockPage) && unref(isPc) && (
{unref(getUseLockPage) && !unref(getIsMobile) && (
<TooltipItem title={t('layout.header.tooltipLock')}>
{() => renderActionDefault(LockOutlined, handleLockPage)}
</TooltipItem>
)}
{unref(getShowNotice) && unref(isPc) && (
{unref(getShowNotice) && !unref(getIsMobile) && (
<TooltipItem title={t('layout.header.tooltipNotify')}>
{() => <NoticeAction />}
</TooltipItem>
)}
{unref(getShowRedo) && unref(isPc) && (
<TooltipItem title={t('layout.header.tooltipRedo')}>
{() => renderActionDefault(RedoOutlined, refreshPage)}
</TooltipItem>
)}
{unref(getShowFullScreen) && !unref(getIsMobile) && <FullScreen />}
<UserDropDown theme={unref(getHeaderTheme)} />
{unref(getShowFullScreen) && unref(isPc) && (
<TooltipItem
title={
unref(isFullscreenRef)
? t('layout.header.tooltipExitFull')
: t('layout.header.tooltipEntryFull')
}
>
{() => {
const Icon = !unref(isFullscreenRef) ? (
<FullscreenOutlined />
) : (
<FullscreenExitOutlined />
);
return renderActionDefault(Icon, toggleFullscreen);
}}
</TooltipItem>
)}
<UserDropdown class="layout-header__user-dropdown" />
{unref(getShowLocale) && (
<AppLocalePicker
reload={true}
showText={false}
class="layout-header__action-item locale"
class={`${prefixCls}__action-item locale`}
/>
)}
</div>
@@ -270,6 +192,10 @@ export default defineComponent({
function renderHeaderDefault() {
return (
<>
{unref(getShowHeaderLogo) && (
<AppLogo class={`${prefixCls}__logo`} theme={unref(getHeaderTheme)} />
)}
{renderHeaderLeft()}
{renderHeaderContent()}
{renderAction()}
<LockAction onRegister={register} />
@@ -279,9 +205,7 @@ export default defineComponent({
return () => {
return (
<Layout.Header
class={['layout-header', 'flex p-0 px-4 ', unref(headerClass), { fixed: props.fixed }]}
>
<Layout.Header class={[prefixCls, unref(headerClass), { fixed: props.fixed }]}>
{() => renderHeaderDefault()}
</Layout.Header>
);