mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 11:54:00 +08:00
wip(menu): perf menu
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
Reference in New Issue
Block a user