mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 16:15:19 +08:00
feat(trigger): add trigger config
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
},
|
||||
|
@@ -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: () => '刷新',
|
||||
|
@@ -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>
|
||||
|
@@ -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
|
||||
|
43
src/layouts/default/LayoutTrigger.tsx
Normal file
43
src/layouts/default/LayoutTrigger.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
@@ -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 />);
|
||||
},
|
||||
});
|
@@ -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 {
|
||||
|
@@ -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} />}
|
||||
|
@@ -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="开"
|
||||
|
Reference in New Issue
Block a user