feat(trigger): add trigger config

This commit is contained in:
vben
2020-11-06 22:41:00 +08:00
parent 58f988a718
commit 4f6b65b8a1
22 changed files with 255 additions and 68 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div class="app-logo anticon" @click="handleGoHome" :style="wrapStyle">
<div class="app-logo anticon" :class="theme" @click="handleGoHome" :style="wrapStyle">
<img :src="logo" />
<div v-if="show" class="logo-title ml-2 ellipsis">{{ globSetting.title }}</div>
</div>
@@ -26,6 +26,9 @@
type: Boolean as PropType<boolean>,
default: true,
},
theme: {
type: String,
},
},
setup(props) {
const showRef = ref<boolean>(!!props.showTitle);
@@ -80,6 +83,9 @@
padding-left: 16px;
cursor: pointer;
// justify-content: center;
&.light {
border-bottom: 1px solid @border-color-base;
}
.logo-title {
font-size: 18px;

View File

@@ -1,5 +1,5 @@
import { defineComponent } from 'vue';
import { Layout } from 'ant-design-vue';
// import { Layout } from 'ant-design-vue';
// hooks
import { ContentEnum } from '/@/enums/appEnum';
@@ -13,9 +13,9 @@ export default defineComponent({
const { contentMode } = getProjectConfig;
const wrapClass = contentMode === ContentEnum.FULL ? 'full' : 'fixed';
return (
<Layout.Content class={`layout-content ${wrapClass} `}>
{() => <PageLayout />}
</Layout.Content>
// <Layout.Content class={`layout-content ${wrapClass} `}>
<PageLayout class={`layout-content ${wrapClass} `} />
// </Layout.Content>
);
};
},

View File

@@ -6,6 +6,7 @@ import UserDropdown from './UserDropdown';
import LayoutMenu from './LayoutMenu';
import LayoutBreadcrumb from './LayoutBreadcrumb';
import LockAction from './actions/LockActionItem';
import LayoutTrigger from './LayoutTrigger';
import NoticeAction from './actions/notice/NoticeActionItem.vue';
import {
RedoOutlined,
@@ -25,7 +26,7 @@ import { useModal } from '/@/components/Modal/index';
import { appStore } from '/@/store/modules/app';
import { errorStore } from '/@/store/modules/error';
import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
import { GITHUB_URL } from '/@/settings/siteSetting';
export default defineComponent({
name: 'DefaultLayoutHeader',
@@ -75,6 +76,13 @@ export default defineComponent({
return theme ? `layout-header__header--${theme}` : '';
});
const showHeaderTrigger = computed(() => {
const { show, trigger, hidden } = unref(getProjectConfigRef).menuSetting;
if (!show || !hidden) return false;
return trigger === TriggerEnum.HEADER;
});
function handleToErrorList() {
errorStore.commitErrorListCountState(0);
push('/exception/error-log');
@@ -92,6 +100,7 @@ export default defineComponent({
const {
useErrorHandle,
showLogo,
multiTabsSetting: { show: showTab },
headerSetting: {
theme: headerTheme,
useLockPage,
@@ -114,11 +123,17 @@ export default defineComponent({
{() => (
<>
<div class="layout-header__content ">
{showLogo && !isSidebarType && <Logo class={`layout-header__logo`} />}
{mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && (
<LayoutBreadcrumb showIcon={showBreadCrumbIcon} />
{showLogo && !isSidebarType && (
<Logo class={`layout-header__logo`} theme={headerTheme} />
)}
<div class="layout-header__left">
{unref(showHeaderTrigger) && <LayoutTrigger theme={headerTheme} sider={false} />}
{mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && (
<LayoutBreadcrumb showIcon={showBreadCrumbIcon} />
)}
</div>
{unref(showTopMenu) && (
<div
class={[`layout-header__menu `]}
@@ -193,7 +208,7 @@ export default defineComponent({
</Tooltip>
</div>
)}
{showRedo && (
{showRedo && showTab && (
<Tooltip>
{{
title: () => '刷新',

View File

@@ -68,9 +68,6 @@ export default defineComponent({
return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL;
});
onMounted(() => {
genMenus();
});
const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50);
// watch(
@@ -90,6 +87,7 @@ export default defineComponent({
immediate: true,
}
);
watch(
[() => permissionStore.getLastBuildMenuTimeState, permissionStore.getBackMenuListState],
() => {
@@ -112,7 +110,7 @@ export default defineComponent({
if (!children) {
appStore.commitProjectConfigState({
menuSetting: {
show: false,
hidden: false,
},
});
flatMenusRef.value = [];
@@ -122,7 +120,7 @@ export default defineComponent({
const flatChildren = await getFlatChildrenMenus(children);
appStore.commitProjectConfigState({
menuSetting: {
show: true,
hidden: true,
},
});
flatMenusRef.value = flatChildren;
@@ -193,6 +191,10 @@ export default defineComponent({
);
});
onMounted(() => {
genMenus();
});
return () => {
const {
showLogo,
@@ -229,7 +231,11 @@ export default defineComponent({
{{
header: () =>
isShowLogo && (
<Logo showTitle={!collapsed} class={[`layout-menu__logo`, themeData]} />
<Logo
showTitle={!collapsed}
class={[`layout-menu__logo`, themeData]}
theme={themeData}
/>
),
}}
</BasicMenu>

View File

@@ -1,14 +1,14 @@
import { computed, defineComponent, nextTick, onMounted, ref, unref } from 'vue';
import { Layout } from 'ant-design-vue';
import SideBarTrigger from './SideBarTrigger';
import LayoutTrigger from './LayoutTrigger';
import { menuStore } from '/@/store/modules/menu';
// import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';
// import lightMiniImg from '/@/assets/images/sidebar/light-mini.png';
// import lightImg from '/@/assets/images/sidebar/light.png';
import { appStore } from '/@/store/modules/app';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum';
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
import { useDebounce } from '/@/hooks/core/useDebounce';
import LayoutMenu from './LayoutMenu';
@@ -133,6 +133,25 @@ export default defineComponent({
return unref(brokenRef) ? 0 : unref(getMiniWidth);
});
const showTrigger = computed(() => {
const {
menuSetting: { trigger },
} = unref(getProjectConfigRef);
return trigger !== TriggerEnum.NONE && trigger === TriggerEnum.FOOTER;
});
function handleSiderClick(e: ChangeEvent) {
if (!e || !e.target || e.target.className !== 'basic-menu__content') return;
const { collapsed, show } = appStore.getProjectConfig.menuSetting;
if (!collapsed || !show) return;
appStore.commitProjectConfigState({
menuSetting: {
collapsed: false,
},
});
}
function renderDragLine() {
const { menuSetting: { hasDrag = true } = {} } = unref(getProjectConfigRef);
return (
@@ -149,8 +168,22 @@ export default defineComponent({
menuSetting: { theme, split: splitMenu },
} = unref(getProjectConfigRef);
const { getCollapsedState, getMenuWidthState } = menuStore;
const triggerDom = unref(showTrigger)
? {
trigger: () => <LayoutTrigger />,
}
: {};
const triggerAttr = unref(showTrigger)
? {}
: {
trigger: null,
};
return (
<Layout.Sider
onClick={handleSiderClick}
onCollapse={onCollapseChange}
breakpoint="md"
width={getMenuWidthState}
@@ -161,9 +194,10 @@ export default defineComponent({
class="layout-sidebar"
ref={sideRef}
onBreakpoint={handleBreakpoint}
{...triggerAttr}
>
{{
trigger: () => <SideBarTrigger />,
...triggerDom,
default: () => (
<>
<LayoutMenu

View File

@@ -0,0 +1,43 @@
import {
DoubleRightOutlined,
DoubleLeftOutlined,
MenuUnfoldOutlined,
MenuFoldOutlined,
} from '@ant-design/icons-vue';
import { defineComponent } from 'vue';
// store
import { menuStore } from '/@/store/modules/menu';
export default defineComponent({
name: 'LayoutTrigger',
props: {
sider: {
type: Boolean,
default: true,
},
theme: {
type: String,
},
},
setup(props) {
function toggleMenu() {
menuStore.commitCollapsedState(!menuStore.getCollapsedState);
}
return () => {
const siderTrigger = menuStore.getCollapsedState ? (
<DoubleRightOutlined />
) : (
<DoubleLeftOutlined />
);
if (props.sider) return siderTrigger;
return (
<span class={['layout-trigger', props.theme]} onClick={toggleMenu}>
{menuStore.getCollapsedState ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
</span>
);
};
},
});

View File

@@ -1,12 +0,0 @@
import { DoubleRightOutlined, DoubleLeftOutlined } from '@ant-design/icons-vue';
import { defineComponent } from 'vue';
// store
import { menuStore } from '/@/store/modules/menu';
export default defineComponent({
name: 'SideBarTrigger',
setup() {
return () => (menuStore.getCollapsedState ? <DoubleRightOutlined /> : <DoubleLeftOutlined />);
},
});

View File

@@ -17,11 +17,10 @@
&__main {
position: relative;
height: 100%;
// overflow: hidden;
// overflow: auto;
&.fixed {
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
&.fixed.lock {
@@ -373,9 +372,39 @@
}
}
.layout-breadcrumb {
padding: 0 16px;
.layout-header__left {
flex-grow: 1;
display: flex;
align-items: center;
.layout-trigger {
padding: 4px 10px 0 16px;
cursor: pointer;
.anticon {
font-size: 17px;
}
&.light {
&:hover {
background: @header-light-bg-hover-color;
}
svg {
fill: #000;
}
}
&.dark {
&:hover {
background: @header-dark-bg-hover-color;
}
}
}
.layout-breadcrumb {
padding: 0 8px;
}
}
.ant-layout-sider-trigger {

View File

@@ -73,7 +73,7 @@ export default defineComponent({
showSettingButton,
multiTabsSetting: { show: showTabs },
headerSetting: { fixed },
menuSetting: { split, show },
menuSetting: { split, hidden },
} = unref(getProjectConfigRef);
const fixedHeaderCls = fixed
@@ -82,7 +82,7 @@ export default defineComponent({
const { isLock } = getLockInfo;
const showSideBar = split ? show : true;
const showSideBar = split ? hidden : true;
return (
<Layout class="default-layout relative">
{() => (
@@ -107,9 +107,7 @@ export default defineComponent({
unref(showHeaderRef) && <LayoutHeader />}
{showTabs && !unref(getFullContent) && (
<Layout.Header class={`default-layout__tabs`}>
{() => <MultipleTabs />}
</Layout.Header>
<MultipleTabs class={`default-layout__tabs`} />
)}
{useOpenBackTop && <BackTop target={getTarget} />}

View File

@@ -2,7 +2,13 @@ import { defineComponent, computed, unref, ref } from 'vue';
import { BasicDrawer } from '/@/components/Drawer/index';
import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue';
import Button from '/@/components/Button/index.vue';
import { MenuModeEnum, MenuTypeEnum, MenuThemeEnum, TopMenuAlignEnum } from '/@/enums/menuEnum';
import {
MenuModeEnum,
MenuTypeEnum,
MenuThemeEnum,
TopMenuAlignEnum,
TriggerEnum,
} from '/@/enums/menuEnum';
import { ContentEnum, RouterTransitionEnum } from '/@/enums/appEnum';
import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue';
import { appStore } from '/@/store/modules/app';
@@ -23,41 +29,49 @@ const themeOptions = [
{
value: MenuThemeEnum.LIGHT,
label: '亮色',
key: MenuThemeEnum.LIGHT,
},
{
value: MenuThemeEnum.DARK,
label: '暗色',
key: MenuThemeEnum.DARK,
},
];
const contentModeOptions = [
{
value: ContentEnum.FULL,
label: '流式',
key: ContentEnum.FULL,
},
{
value: ContentEnum.FIXED,
label: '定宽',
key: ContentEnum.FIXED,
},
];
const topMenuAlignOptions = [
{
value: TopMenuAlignEnum.CENTER,
label: '居中',
key: TopMenuAlignEnum.CENTER,
},
{
value: TopMenuAlignEnum.START,
label: '居左',
key: TopMenuAlignEnum.START,
},
{
value: TopMenuAlignEnum.END,
label: '居右',
key: TopMenuAlignEnum.END,
},
];
const menuTriggerOptions = [
{
value: TriggerEnum.NONE,
label: '不显示',
},
{
value: TriggerEnum.FOOTER,
label: '底部',
},
{
value: TriggerEnum.HEADER,
label: '顶部',
},
];
@@ -181,7 +195,7 @@ export default defineComponent({
baseHandler('splitMenu', e);
},
def: split,
disabled: !unref(getShowMenuRef),
disabled: !unref(getShowMenuRef) || type !== MenuTypeEnum.MIX,
}),
renderSelectItem('顶栏主题', {
handler: (e) => {
@@ -215,6 +229,7 @@ export default defineComponent({
menuWidth,
topMenuAlign,
collapsedShowTitle,
trigger,
} = {},
} = appStore.getProjectConfig;
return [
@@ -262,6 +277,13 @@ export default defineComponent({
options: topMenuAlignOptions,
disabled: !unref(getShowHeaderRef),
}),
renderSelectItem('菜单折叠按钮', {
handler: (e) => {
baseHandler('menuTrigger', e);
},
def: trigger,
options: menuTriggerOptions,
}),
renderSelectItem('内容区域宽度', {
handler: (e) => {
baseHandler('contentMode', e);
@@ -298,7 +320,7 @@ export default defineComponent({
disabled={!unref(getShowMenuRef)}
defaultValue={menuWidth}
formatter={(value: string) => `${parseInt(value)}px`}
onChange={(e) => {
onChange={(e: any) => {
baseHandler('menuWidth', e);
}}
/>
@@ -424,13 +446,21 @@ export default defineComponent({
if (event === 'layout') {
const { mode, type, split } = value;
const splitOpt = split === undefined ? { split } : {};
let headerSetting = {};
if (type === MenuTypeEnum.TOP_MENU) {
headerSetting = {
theme: MenuThemeEnum.DARK,
};
}
config = {
menuSetting: {
mode,
type,
collapsed: false,
show: true,
...splitOpt,
},
headerSetting,
};
}
if (event === 'hasDrag') {
@@ -440,6 +470,13 @@ export default defineComponent({
},
};
}
if (event === 'menuTrigger') {
config = {
menuSetting: {
trigger: value,
},
};
}
if (event === 'openPageLoading') {
config = {
openPageLoading: value,
@@ -647,7 +684,7 @@ export default defineComponent({
<Switch
{...opt}
disabled={disabled}
onChange={(e) => {
onChange={(e: any) => {
handler && handler(e);
}}
checkedChildren="开"