提交 96c10d6c 作者: vben

perf(menu): optimize layout menu

上级 d3780690
## Wip
### ⚡ Performance Improvements
- 菜单性能继续优化
### 🎫 Chores
- 删除菜单背景图
## 2.0.0-rc.8 (2020-11-2) ## 2.0.0-rc.8 (2020-11-2)
### ✨ Features ### ✨ Features
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
}, },
"dependencies": { "dependencies": {
"@iconify/iconify": "^2.0.0-rc.1", "@iconify/iconify": "^2.0.0-rc.1",
"ant-design-vue": "^2.0.0-beta.12", "ant-design-vue": "^2.0.0-beta.13",
"apexcharts": "^3.22.0", "apexcharts": "^3.22.0",
"axios": "^0.21.0", "axios": "^0.21.0",
"echarts": "^4.9.0", "echarts": "^4.9.0",
......
...@@ -35,9 +35,11 @@ ...@@ -35,9 +35,11 @@
@import (reference) '../../design/index.less'; @import (reference) '../../design/index.less';
.breadcrumb { .breadcrumb {
.unselect();
height: @header-height; height: @header-height;
padding-right: 20px; padding-right: 20px;
font-size: 14px; font-size: 13px;
line-height: @header-height; line-height: @header-height;
// line-height: 1; // line-height: 1;
......
...@@ -72,7 +72,7 @@ export default defineComponent({ ...@@ -72,7 +72,7 @@ export default defineComponent({
onMounted(update); onMounted(update);
return () => ( return () => (
<div ref={elRef} class={[attrs.class, 'app-iconify']} style={unref(wrapStyleRef)} /> <div ref={elRef} class={[attrs.class, 'app-iconify anticon']} style={unref(wrapStyleRef)} />
); );
}, },
}); });
...@@ -2,21 +2,27 @@ import type { MenuState } from './types'; ...@@ -2,21 +2,27 @@ import type { MenuState } from './types';
import type { Menu as MenuType } from '/@/router/types'; import type { Menu as MenuType } from '/@/router/types';
import { computed, defineComponent, unref, reactive, toRef, watch, onMounted, ref } from 'vue'; import { computed, defineComponent, unref, reactive, toRef, watch, onMounted, ref } from 'vue';
import { basicProps } from './props';
import { Menu } from 'ant-design-vue'; import { Menu } from 'ant-design-vue';
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
import { menuStore } from '/@/store/modules/menu';
import { getSlot } from '/@/utils/helper/tsxHelper';
// import { ScrollContainer } from '/@/components/Container/index';
import SearchInput from './SearchInput.vue'; import SearchInput from './SearchInput.vue';
import './index.less';
import { menuHasChildren } from './helper';
import MenuContent from './MenuContent'; import MenuContent from './MenuContent';
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
import { menuStore } from '/@/store/modules/menu';
import { appStore } from '/@/store/modules/app';
import { useSearchInput } from './useSearchInput'; import { useSearchInput } from './useSearchInput';
import { useOpenKeys } from './useOpenKeys'; import { useOpenKeys } from './useOpenKeys';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { isFunction } from '/@/utils/is'; import { isFunction } from '/@/utils/is';
import { getSlot } from '/@/utils/helper/tsxHelper';
import { menuHasChildren } from './helper';
import { getCurrentParentPath } from '/@/router/menus'; import { getCurrentParentPath } from '/@/router/menus';
import { basicProps } from './props';
import './index.less';
export default defineComponent({ export default defineComponent({
name: 'BasicMenu', name: 'BasicMenu',
props: basicProps, props: basicProps,
...@@ -69,7 +75,7 @@ export default defineComponent({ ...@@ -69,7 +75,7 @@ export default defineComponent({
return { return {
height: `calc(100% - ${offset - 10}px)`, height: `calc(100% - ${offset - 10}px)`,
position: 'relative', position: 'relative',
overflow: 'auto', overflowY: 'auto',
}; };
}); });
...@@ -77,26 +83,26 @@ export default defineComponent({ ...@@ -77,26 +83,26 @@ export default defineComponent({
const transparentMenuClass = computed(() => { const transparentMenuClass = computed(() => {
const { type } = props; const { type } = props;
const { mode } = menuState; const { mode } = menuState;
if ( const cls: string[] = [];
[MenuTypeEnum.MIX, MenuTypeEnum.SIDEBAR].includes(type) &&
mode !== MenuModeEnum.HORIZONTAL
) {
return `basic-menu-bg__sidebar`;
}
if ( if (
(type === MenuTypeEnum.TOP_MENU && mode === MenuModeEnum.HORIZONTAL) || (type === MenuTypeEnum.TOP_MENU && mode === MenuModeEnum.HORIZONTAL) ||
props.appendClass props.appendClass
) { ) {
return `basic-menu-bg__sidebar-hor`; cls.push('basic-menu__sidebar-hor');
} }
return '';
if (!props.isTop && props.isAppMenu && appStore.getProjectConfig.menuSetting.split) {
cls.push('basic-menu__second');
}
return cls;
}); });
watch( watch(
() => currentRoute.value.name, () => currentRoute.value.name,
(name: string) => { (name: string) => {
name !== 'Redirect' && handleMenuChange(); if (name === 'Redirect') return;
getParentPath(); handleMenuChange();
props.isTop && appStore.getProjectConfig.menuSetting.split && getParentPath();
} }
); );
...@@ -149,22 +155,14 @@ export default defineComponent({ ...@@ -149,22 +155,14 @@ export default defineComponent({
} }
const showTitle = computed(() => { const showTitle = computed(() => {
if (props.isTop) return true; return props.collapsedShowTitle && menuStore.getCollapsedState;
if (!props.isAppMenu) return true;
if (!props.collapsedShowTitle) {
return !menuStore.getCollapsedState;
}
return true;
}); });
// render menu item // render menu item
function renderMenuItem(menuList?: MenuType[], index = 1) { function renderMenuItem(menuList?: MenuType[], index = 1) {
if (!menuList) { if (!menuList) return;
return;
}
const { appendClass } = props; const { appendClass } = props;
const levelCls = `basic-menu-item__level${index} ${menuState.theme} `; const levelCls = `basic-menu-item__level${index} ${menuState.theme} `;
return menuList.map((menu) => { return menuList.map((menu) => {
if (!menu) { if (!menu) {
return null; return null;
...@@ -233,7 +231,7 @@ export default defineComponent({ ...@@ -233,7 +231,7 @@ export default defineComponent({
class={[ class={[
'basic-menu', 'basic-menu',
props.collapsedShowTitle && 'collapsed-show-title', props.collapsedShowTitle && 'collapsed-show-title',
unref(transparentMenuClass), ...unref(transparentMenuClass),
]} ]}
{...inlineCollapsedObj} {...inlineCollapsedObj}
> >
...@@ -247,6 +245,7 @@ export default defineComponent({ ...@@ -247,6 +245,7 @@ export default defineComponent({
onMounted(async () => { onMounted(async () => {
getParentPath(); getParentPath();
}); });
return () => { return () => {
const { getCollapsedState } = menuStore; const { getCollapsedState } = menuStore;
const { mode } = props; const { mode } = props;
...@@ -262,9 +261,8 @@ export default defineComponent({ ...@@ -262,9 +261,8 @@ export default defineComponent({
onClick={handleInputClick} onClick={handleInputClick}
collapsed={getCollapsedState} collapsed={getCollapsedState}
/> />
<section style={unref(getMenuWrapStyle)} class="basic-menu__wrap"> <section style={unref(getMenuWrapStyle)} class="basic-menu__content">
{renderMenu()} {renderMenu()}
{/* <ScrollContainer>{() => renderMenu()}</ScrollContainer> */}
</section> </section>
</section> </section>
); );
......
...@@ -11,14 +11,17 @@ export default defineComponent({ ...@@ -11,14 +11,17 @@ export default defineComponent({
type: String as PropType<string>, type: String as PropType<string>,
default: '', default: '',
}, },
item: { item: {
type: Object as PropType<MenuType>, type: Object as PropType<MenuType>,
default: null, default: null,
}, },
showTitle: { showTitle: {
type: Boolean as PropType<boolean>, type: Boolean as PropType<boolean>,
default: true, default: true,
}, },
level: { level: {
type: Number as PropType<number>, type: Number as PropType<number>,
default: 0, default: 0,
...@@ -36,26 +39,27 @@ export default defineComponent({ ...@@ -36,26 +39,27 @@ export default defineComponent({
if (!props.item) { if (!props.item) {
return null; return null;
} }
const { showTitle, level } = props; const { showTitle } = props;
const { name, icon } = props.item; const { name, icon } = props.item;
const searchValue = props.searchValue || ''; const searchValue = props.searchValue || '';
const index = name.indexOf(searchValue); const index = name.indexOf(searchValue);
const beforeStr = name.substr(0, index); const beforeStr = name.substr(0, index);
const afterStr = name.substr(index + searchValue.length); const afterStr = name.substr(index + searchValue.length);
const show = level === 1 ? showTitle : true; return (
return [ <>
renderIcon(icon!), {renderIcon(icon!)}
index > -1 && searchValue ? ( {index > -1 && searchValue ? (
<span class={!show && 'hidden'}> <span class={showTitle ? 'show-title' : ''}>
{beforeStr} {beforeStr}
<span class={`basic-menu__keyword`}>{searchValue}</span> <span class={`basic-menu__keyword`}>{searchValue}</span>
{afterStr} {afterStr}
</span> </span>
) : ( ) : (
<span class={!show && 'hidden'}>{name}</span> <span class={[showTitle ? 'show-title' : '']}>{name}</span>
), )}
]; </>
);
}; };
}, },
}); });
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
class="menu-search-input__search" class="menu-search-input__search"
allowClear allowClear
@change="handleChange" @change="handleChange"
:disabled="collapsed"
/> />
</section> </section>
</template> </template>
...@@ -20,7 +19,7 @@ ...@@ -20,7 +19,7 @@
export default defineComponent({ export default defineComponent({
name: 'BasicMenuSearchInput', name: 'BasicMenuSearchInput',
props: { props: {
// 是否展开,用于左侧菜单 // Whether to expand, used in the left menu
collapsed: { collapsed: {
type: Boolean as PropType<boolean>, type: Boolean as PropType<boolean>,
default: true, default: true,
...@@ -30,28 +29,27 @@ ...@@ -30,28 +29,27 @@
}, },
}, },
setup(props, { emit }) { setup(props, { emit }) {
const [debounceEmitChange] = useDebounce(emitChange, 200);
function emitChange(value?: string): void { function emitChange(value?: string): void {
emit('change', value); emit('change', value);
} }
const [debounceEmitChange] = useDebounce(emitChange, 200);
/**
* @description: 搜索
*/
function handleChange(e: ChangeEvent): void { function handleChange(e: ChangeEvent): void {
const { collapsed } = props; const { collapsed } = props;
if (collapsed) { if (collapsed) return;
return;
}
debounceEmitChange(e.target.value); debounceEmitChange(e.target.value);
} }
/**
* @description: 点击时间
*/
function handleClick(): void { function handleClick(): void {
emit('click'); emit('click');
} }
const searchClass = computed(() => { const searchClass = computed(() => {
return props.theme ? `menu-search-input__search--${props.theme}` : ''; const cls: string[] = [];
cls.push(props.theme ? `menu-search-input__search--${props.theme}` : '');
// cls.push(props.collapsed ? 'hide-search-icon' : '');
return cls;
}); });
return { handleClick, searchClass, handleChange }; return { handleClick, searchClass, handleChange };
...@@ -66,26 +64,24 @@ ...@@ -66,26 +64,24 @@
@icon-color: #c0c4cc; @icon-color: #c0c4cc;
.menu-search-input { .menu-search-input {
margin: 12px 9px; margin: 12px 8px;
// &.hide-search-icon {
// .ant-input,
// .ant-input-suffix {
// opacity: 0;
// }
// }
&__search--dark { &__search--dark {
.ant-input-affix-wrapper, .ant-input-affix-wrapper,
.ant-input { .ant-input {
.set-bg(); .set-bg();
&:hover,
&:focus {
.hide-outline();
}
} }
.ant-input-search-icon, .ant-input-search-icon,
.ant-input-clear-icon { .ant-input-clear-icon {
color: rgba(255, 255, 255, 0.6) !important; color: rgba(255, 255, 255, 0.4) !important;
}
.ant-input-clear-icon {
color: rgba(255, 255, 255, 0.3) !important;
} }
} }
...@@ -94,13 +90,7 @@ ...@@ -94,13 +90,7 @@
.ant-input { .ant-input {
color: @text-color-base; color: @text-color-base;
background: #fff; background: #fff;
// border: 0;
outline: none; outline: none;
&:hover,
&:focus {
.hide-outline();
}
} }
.ant-input-search-icon { .ant-input-search-icon {
......
...@@ -2,14 +2,11 @@ ...@@ -2,14 +2,11 @@
.active-style() { .active-style() {
color: @white; color: @white;
// background: @primary-color !important;
background: linear-gradient( background: linear-gradient(
118deg, 118deg,
rgba(@primary-color, 0.8), rgba(@primary-color, 0.8),
rgba(@primary-color, 1) rgba(@primary-color, 1)
) !important; ) !important;
// border-radius: 2px;
box-shadow: 0 0 4px 1px rgba(@primary-color, 0.7);
} }
.active-menu-style() { .active-menu-style() {
...@@ -22,50 +19,52 @@ ...@@ -22,50 +19,52 @@
.basic-menu { .basic-menu {
width: 100%; width: 100%;
&-wrap {
height: 100%;
}
// collapsed show title start
.show-title {
max-width: unset !important;
opacity: 1 !important;
}
&.collapsed-show-title.ant-menu-inline-collapsed { &.collapsed-show-title.ant-menu-inline-collapsed {
.basic-menu-item__level1 { .basic-menu-item__level1 {
padding: 2px 0; padding: 2px 0;
} }
& > li[role='menuitem']:not(.ant-menu-submenu),
& > li > .ant-menu-submenu-title { & > li > .ant-menu-submenu-title {
display: flex; display: flex;
margin-top: 12px; margin-top: 10px;
font-size: 12px; font-size: 12px;
flex-direction: column; flex-direction: column;
line-height: 24px;
align-items: center; align-items: center;
} }
& > li[role='menuitem']:not(.ant-menu-submenu) { & > li > .ant-menu-submenu-title {
display: flex; line-height: 24px;
margin-top: 12px;
font-size: 12px;
line-height: 2;
align-items: center;
flex-direction: column;
span {
margin-top: 6px;
}
} }
} }
&__wrap { // collapsed show title end
// scrollbar -s tart
&__content {
/* 滚动槽 */ /* 滚动槽 */
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 6px; width: 4px;
height: 6px; height: 4px;
} }
// TODO 滚动条样式-待修改
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0); background: rgba(0, 0, 0, 0);
} }
/* 滚动条滑块 */
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.3); background: rgba(255, 255, 255, 0.2);
border-radius: 4px; border-radius: 3px;
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
} }
...@@ -73,29 +72,10 @@ ...@@ -73,29 +72,10 @@
background: @border-color-dark; background: @border-color-dark;
} }
} }
// scrollbar end
.ant-menu-submenu:first-of-type { &__sidebar-hor {
margin-top: 4px; // overflow: hidden;
}
.ant-menu-submenu-title {
margin-top: 0;
}
&-wrap {
height: 100%;
}
.menu-item-icon {
vertical-align: text-top;
}
// 透明化背景
&-bg__sidebar {
background-color: transparent;
}
&-bg__sidebar-hor {
overflow: hidden;
&.ant-menu-horizontal { &.ant-menu-horizontal {
display: flex; display: flex;
...@@ -107,6 +87,13 @@ ...@@ -107,6 +87,13 @@
} }
&.ant-menu-light { &.ant-menu-light {
.basic-menu-item__level1 {
&.top-active-menu {
color: @primary-color;
border-bottom: 3px solid @primary-color;
}
}
.ant-menu-item { .ant-menu-item {
&.basic-menu-item__level1 { &.basic-menu-item__level1 {
height: @header-height; height: @header-height;
...@@ -128,7 +115,6 @@ ...@@ -128,7 +115,6 @@
border-bottom: 3px solid @primary-color; border-bottom: 3px solid @primary-color;
} }
// 有子菜单
.ant-menu-submenu { .ant-menu-submenu {
&:hover { &:hover {
border-bottom: 3px solid @primary-color; border-bottom: 3px solid @primary-color;
...@@ -144,30 +130,44 @@ ...@@ -144,30 +130,44 @@
&.ant-menu-dark { &.ant-menu-dark {
background: transparent; background: transparent;
.ant-menu-submenu:hover,
.ant-menu-item-open,
.ant-menu-submenu-open,
.ant-menu-item-selected,
.ant-menu-submenu-selected,
.ant-menu-item:hover,
.ant-menu-item-active,
.ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open,
.ant-menu-submenu-active,
.ant-menu-submenu-title:hover {
color: #fff;
background: @top-menu-active-bg-color !important;
}
.ant-menu-item:hover, .ant-menu-item:hover,
.ant-menu-item-active, .ant-menu-item-active,
.ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open,
.ant-menu-submenu-active, .ant-menu-submenu-active,
.ant-menu-submenu-title:hover { .ant-menu-submenu-title:hover {
background: @top-menu-active-bg-color; background: @top-menu-active-bg-color;
// border-radius: 6px 6px 0 0;
} }
.basic-menu-item__level1 { .basic-menu-item__level1 {
&.ant-menu-item-selected, background: transparent;
&.ant-menu-submenu-selected {
&.top-active-menu {
color: @white;
background: @top-menu-active-bg-color; background: @top-menu-active-bg-color;
// border-radius: 6px 6px 0 0; border-radius: 2px 2px 0 0;
} }
}
.ant-menu-item { &.ant-menu-item-selected,
&.basic-menu-item__level1 { &.ant-menu-submenu-selected {
height: @header-height; background: @top-menu-active-bg-color !important;
line-height: @header-height;
} }
} }
// 有子菜单
.ant-menu-item,
.ant-menu-submenu { .ant-menu-submenu {
&.basic-menu-item__level1, &.basic-menu-item__level1,
.ant-menu-submenu-title { .ant-menu-submenu-title {
...@@ -178,24 +178,27 @@ ...@@ -178,24 +178,27 @@
} }
} }
} }
// 重置菜单项行高
.ant-menu-item, .ant-menu-item {
.ant-menu-sub.ant-menu-inline > .ant-menu-item, transition: unset;
.ant-menu-sub.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title {
height: @app-menu-item-height;
margin: 0;
line-height: @app-menu-item-height;
} }
&.ant-menu-dark:not(.basic-menu-bg__sidebar-hor) { &.ant-menu-dark:not(.basic-menu__sidebar-hor):not(.basic-menu__second) {
.active-menu-style(); // Reset menu item row height
.ant-menu-item,
.ant-menu-sub.ant-menu-inline > .ant-menu-item,
.ant-menu-sub.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title {
height: @app-menu-item-height;
margin: 0;
line-height: @app-menu-item-height;
}
} }
// 层级样式 // 层级样式
&.ant-menu-dark { &.ant-menu-dark:not(.basic-menu__sidebar-hor) {
// .ant-menu-item { overflow-x: hidden;
// transition: unset; background: @first-menu-item-dark-bg-color;
// } .active-menu-style();
.ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1, .ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1,
.ant-menu-submenu-selected.basic-menu-menu-item__level1 { .ant-menu-submenu-selected.basic-menu-menu-item__level1 {
...@@ -203,76 +206,44 @@ ...@@ -203,76 +206,44 @@
} }
.basic-menu-item__level1 { .basic-menu-item__level1 {
margin-bottom: 0; background-color: @first-menu-item-dark-bg-color;
> .ant-menu-sub > li { > .ant-menu-sub > li {
background-color: @sub-menu-item-dark-bg-color; background-color: @sub-menu-item-dark-bg-color;
} }
&.top-active-menu {
color: @white;
background: @top-menu-active-bg-color;
border-radius: 6px 6px 0 0;
}
} }
// 2级菜单
.basic-menu-item__level2:not(.ant-menu-item-selected), .basic-menu-item__level2:not(.ant-menu-item-selected),
.ant-menu-sub { .ant-menu-sub {
background-color: @sub-menu-item-dark-bg-color; background-color: @sub-menu-item-dark-bg-color;
} }
.basic-menu-item__level2 {
margin-bottom: 0;
}
// 3级菜单
.basic-menu-item__level3,
.basic-menu__popup {
margin-bottom: 0;
}
.basic-menu-item__level3:not(.ant-menu-item-selected) { .basic-menu-item__level3:not(.ant-menu-item-selected) {
background-color: @children-menu-item-dark-bg-color; background-color: @children-menu-item-dark-bg-color;
} }
.ant-menu-submenu-title { .ant-menu-submenu-title {
// line-height: @app-menu-item-height;
display: flex; display: flex;
height: @app-menu-item-height; height: @app-menu-item-height;
margin: 0; // margin: 0;
align-items: center; align-items: center;
} }
&.ant-menu-inline-collapsed { &.ant-menu-inline-collapsed {
.ant-menu-item-selected {
background: unset !important;
box-shadow: none;
}
.ant-menu-submenu-selected, .ant-menu-submenu-selected,
.ant-menu-item-selected { .ant-menu-item-selected {
.active-style(); background: darken(@first-menu-item-dark-bg-color, 6%) !important;
} }
} }
} }
&.ant-menu-light { &.ant-menu-light:not(.basic-menu__sidebar-hor) {
overflow-x: hidden; overflow-x: hidden;
border-right: none; border-right: none;
.basic-menu-item__level1 { // .ant-menu-item-selected {
&.top-active-menu { // background: fade(@primary-color, 18%);
color: @primary-color; // }
border-bottom: 3px solid @primary-color;
}
}
&:not(.ant-menu-horizontal) {
.ant-menu-item-selected {
background: fade(@primary-color, 18%);
}
}
.ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1, .ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1,
.ant-menu-submenu-selected.basic-menu-menu-item__level1 { .ant-menu-submenu-selected.basic-menu-menu-item__level1 {
...@@ -289,6 +260,20 @@ ...@@ -289,6 +260,20 @@
.ant-menu-item.ant-menu-item-selected { .ant-menu-item.ant-menu-item-selected {
position: relative; position: relative;
} }
&.basic-menu__second.ant-menu-inline-collapsed:not(.basic-menu__sidebar-hor) {
// Reset menu item row height
.ant-menu-item,
.ant-menu-sub.ant-menu-inline > .ant-menu-item,
.ant-menu-sub.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title {
display: flex;
height: @app-menu-item-height * 1.4;
padding: 6px 0 !important;
margin: 0;
line-height: @app-menu-item-height;
align-items: center;
}
}
} }
// 触发器样式 // 触发器样式
...@@ -322,3 +307,24 @@ ...@@ -322,3 +307,24 @@
.active-menu-style(); .active-menu-style();
} }
} }
.hide-title {
.ant-menu-inline-collapsed > .ant-menu-item,
.ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item,
.ant-menu-inline-collapsed
> .ant-menu-item-group
> .ant-menu-item-group-list
> .ant-menu-submenu
> .ant-menu-submenu-title,
.ant-menu-inline-collapsed > .ant-menu-submenu > .ant-menu-submenu-title {
padding-right: 20px !important;
padding-left: 20px !important;
}
.ant-menu-inline-collapsed {
.basic-menu-item__level1 {
display: flex;
justify-content: center;
}
}
}
// button重置 // button重置
.ant-btn { .ant-btn {
&.ant-btn-success:not(.ant-btn-link), // &.ant-btn-success:not(.ant-btn-link),
&.ant-btn-error:not(.ant-btn-link), // &.ant-btn-error:not(.ant-btn-link),
&.ant-btn-warning:not(.ant-btn-link), // &.ant-btn-warning:not(.ant-btn-link),
&.ant-btn-primary:not(.ant-btn-link) { // &.ant-btn-primary:not(.ant-btn-link) {
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.12), 0 2px 4px 0 rgba(0, 0, 0, 0.08) !important; // box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.12), 0 2px 4px 0 rgba(0, 0, 0, 0.08) !important;
} // }
&-primary { &-primary {
color: @white; color: @white;
......
...@@ -67,9 +67,9 @@ ...@@ -67,9 +67,9 @@
@first-menu-item-dark-bg-color: #273352; @first-menu-item-dark-bg-color: #273352;
// 2级菜单黑暗背景色 // 2级菜单黑暗背景色
@sub-menu-item-dark-bg-color: #4f6088; @sub-menu-item-dark-bg-color: #314268;
// 3级菜单黑暗背景色 // 3级菜单黑暗背景色
@children-menu-item-dark-bg-color: #314268; @children-menu-item-dark-bg-color: #4f6088;
// top-menu // top-menu
@top-menu-active-bg-color: #273352; @top-menu-active-bg-color: #273352;
......
/* 滚动槽 */ /* 滚动槽 */
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 8px; width: 6px;
height: 8px; height: 6px;
} }
// TODO 滚动条样式-待修改 // TODO 滚动条样式-待修改
// ::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
// // background: rgba(0, 0, 0, 0.06); background: rgba(0, 0, 0, 0.05);
// // border-radius: 2px; }
// // box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
// }
/* 滚动条滑块 */ /* 滚动条滑块 */
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background: @disabled-color; background: rgba(0, 0, 0, 0.2);
border-radius: 4px; border-radius: 4px;
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
} }
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
@logo-width: 36px; @logo-width: 36px;
// //
@sider-drag-z-index: 200; @side-drag-z-index: 200;
@page-loading-z-index: 10000; @page-loading-z-index: 10000;
// app menu // app menu
......
...@@ -75,7 +75,7 @@ export default defineComponent({ ...@@ -75,7 +75,7 @@ export default defineComponent({
} }
return () => ( return () => (
<Breadcrumb class="layout-breadcrumb"> <Breadcrumb class={['layout-breadcrumb', unref(itemList).length === 0 ? 'hidden' : '']}>
{() => ( {() => (
<TransitionGroup name="breadcrumb"> <TransitionGroup name="breadcrumb">
{() => { {() => {
......
...@@ -109,8 +109,22 @@ export default defineComponent({ ...@@ -109,8 +109,22 @@ export default defineComponent({
// 菜单分割模式-left // 菜单分割模式-left
if (splitType === MenuSplitTyeEnum.LEFT) { if (splitType === MenuSplitTyeEnum.LEFT) {
const children = await getChildrenMenus(parentPath); const children = await getChildrenMenus(parentPath);
if (!children) return; if (!children) {
appStore.commitProjectConfigState({
menuSetting: {
show: false,
},
});
flatMenusRef.value = [];
menusRef.value = [];
return;
}
const flatChildren = await getFlatChildrenMenus(children); const flatChildren = await getFlatChildrenMenus(children);
appStore.commitProjectConfigState({
menuSetting: {
show: true,
},
});
flatMenusRef.value = flatChildren; flatMenusRef.value = flatChildren;
menusRef.value = children; menusRef.value = children;
} }
......
...@@ -6,10 +6,9 @@ import { menuStore } from '/@/store/modules/menu'; ...@@ -6,10 +6,9 @@ import { menuStore } from '/@/store/modules/menu';
// import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png'; // import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';
// import lightMiniImg from '/@/assets/images/sidebar/light-mini.png'; // import lightMiniImg from '/@/assets/images/sidebar/light-mini.png';
import darkImg from '/@/assets/images/sidebar/dark.png';
// import lightImg from '/@/assets/images/sidebar/light.png'; // import lightImg from '/@/assets/images/sidebar/light.png';
import { appStore } from '/@/store/modules/app'; import { appStore } from '/@/store/modules/app';
import { MenuModeEnum, MenuSplitTyeEnum, MenuThemeEnum } from '/@/enums/menuEnum'; import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
import { useDebounce } from '/@/hooks/core/useDebounce'; import { useDebounce } from '/@/hooks/core/useDebounce';
import LayoutMenu from './LayoutMenu'; import LayoutMenu from './LayoutMenu';
...@@ -34,26 +33,6 @@ export default defineComponent({ ...@@ -34,26 +33,6 @@ export default defineComponent({
return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH; return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
}); });
// 根据展开状态设置背景图片
const getStyle = computed((): any => {
// const collapse = unref(collapseRef);
const theme = unref(getProjectConfigRef).menuSetting.theme;
if (theme === MenuThemeEnum.LIGHT) {
// bg = lightImg;
return {};
}
let bg = '';
if (theme === MenuThemeEnum.DARK) {
// bg = collapse ? darkMiniIMg : darkImg;
bg = darkImg;
}
return {
'background-image': `url(${bg})`,
};
});
function onCollapseChange(val: boolean) { function onCollapseChange(val: boolean) {
if (initRef.value) { if (initRef.value) {
collapseRef.value = val; collapseRef.value = val;
...@@ -182,7 +161,6 @@ export default defineComponent({ ...@@ -182,7 +161,6 @@ export default defineComponent({
class="layout-sidebar" class="layout-sidebar"
ref={sideRef} ref={sideRef}
onBreakpoint={handleBreakpoint} onBreakpoint={handleBreakpoint}
style={unref(getStyle)}
> >
{{ {{
trigger: () => <SideBarTrigger />, trigger: () => <SideBarTrigger />,
......
...@@ -26,14 +26,12 @@ export default defineComponent({ ...@@ -26,14 +26,12 @@ export default defineComponent({
return { realName, desc }; return { realName, desc };
}); });
/** // login out
* @description: 退出登录
*/
function handleLoginOut() { function handleLoginOut() {
userStore.confirmLoginOut(); userStore.confirmLoginOut();
} }
// 打开文档 // open doc
function openDoc() { function openDoc() {
window.open(DOC_URL, '__blank'); window.open(DOC_URL, '__blank');
} }
......
...@@ -66,6 +66,10 @@ ...@@ -66,6 +66,10 @@
.layout-sidebar { .layout-sidebar {
background-size: 100% 100%; background-size: 100% 100%;
&.ant-layout-sider-dark {
background: @first-menu-item-dark-bg-color;
}
&:not(.ant-layout-sider-dark) { &:not(.ant-layout-sider-dark) {
border-right: 1px solid @border-color-light; border-right: 1px solid @border-color-light;
} }
...@@ -79,7 +83,7 @@ ...@@ -79,7 +83,7 @@
position: absolute; position: absolute;
top: 0; top: 0;
right: -2px; right: -2px;
z-index: @sider-drag-z-index; z-index: @side-drag-z-index;
width: 2px; width: 2px;
height: 100%; height: 100%;
cursor: col-resize; cursor: col-resize;
...@@ -378,17 +382,3 @@ ...@@ -378,17 +382,3 @@
height: 36px; height: 36px;
line-height: 36px; line-height: 36px;
} }
.hide-title {
.ant-menu-inline-collapsed > .ant-menu-item,
.ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item,
.ant-menu-inline-collapsed
> .ant-menu-item-group
> .ant-menu-item-group-list
> .ant-menu-submenu
> .ant-menu-submenu-title,
.ant-menu-inline-collapsed > .ant-menu-submenu > .ant-menu-submenu-title {
padding-right: 20px !important;
padding-left: 20px !important;
}
}
...@@ -51,9 +51,9 @@ export default defineComponent({ ...@@ -51,9 +51,9 @@ export default defineComponent({
const showSideBarRef = computed(() => { const showSideBarRef = computed(() => {
const { const {
menuSetting: { show, mode }, menuSetting: { show, mode, split },
} = unref(getProjectConfigRef); } = unref(getProjectConfigRef);
return show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent); return split || (show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent));
}); });
// Get project configuration // Get project configuration
...@@ -73,6 +73,7 @@ export default defineComponent({ ...@@ -73,6 +73,7 @@ export default defineComponent({
showSettingButton, showSettingButton,
multiTabsSetting: { show: showTabs }, multiTabsSetting: { show: showTabs },
headerSetting: { fixed }, headerSetting: { fixed },
menuSetting: { split, show },
} = unref(getProjectConfigRef); } = unref(getProjectConfigRef);
const fixedHeaderCls = fixed const fixedHeaderCls = fixed
...@@ -80,6 +81,8 @@ export default defineComponent({ ...@@ -80,6 +81,8 @@ export default defineComponent({
: ''; : '';
const { isLock } = getLockInfo; const { isLock } = getLockInfo;
const showSideBar = split ? show : true;
return ( return (
<Layout class="default-layout relative"> <Layout class="default-layout relative">
{() => ( {() => (
...@@ -95,7 +98,7 @@ export default defineComponent({ ...@@ -95,7 +98,7 @@ export default defineComponent({
<Layout> <Layout>
{() => ( {() => (
<> <>
{unref(showSideBarRef) && <LayoutSideBar />} {unref(showSideBarRef) && <LayoutSideBar class={showSideBar ? '' : 'hidden'} />}
<Layout class={[`default-layout__content`, fixedHeaderCls]}> <Layout class={[`default-layout__content`, fixedHeaderCls]}>
{() => ( {() => (
<> <>
......
...@@ -38,14 +38,16 @@ export default defineComponent({ ...@@ -38,14 +38,16 @@ export default defineComponent({
<RouterView> <RouterView>
{{ {{
default: ({ Component, route }: { Component: any; route: RouteLocation }) => { default: ({ Component, route }: { Component: any; route: RouteLocation }) => {
// 已经位于tab内的不再显示动画 // No longer show animations that are already in the tab
const name = route.meta.inTab ? 'fade' : null; const name = route.meta.inTab ? 'fade' : null;
// TODO add key?
const Content = openCache ? ( const Content = openCache ? (
<KeepAlive max={max} include={cacheTabs}> <KeepAlive max={max} include={cacheTabs}>
<Component {...route.params} /> <Component />
</KeepAlive> </KeepAlive>
) : ( ) : (
<Component {...route.params} /> <Component />
); );
return openRouterTransition ? ( return openRouterTransition ? (
<Transition <Transition
......
import { onUnmounted } from 'vue';
import { appStore } from '/@/store/modules/app'; import { appStore } from '/@/store/modules/app';
import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
export function useTransition() { export function useTransition() {
function handleAfterEnter() { function handleAfterEnter() {
const { openRouterTransition, openPageLoading } = appStore.getProjectConfig; const { openRouterTransition, openPageLoading } = appStore.getProjectConfig;
if (!openRouterTransition || !openPageLoading) return; if (!openRouterTransition || !openPageLoading) return;
// 路由切换动画结束之后关闭loading // Close loading after the route switching animation ends
appStore.setPageLoadingAction(false); appStore.setPageLoadingAction(false);
} }
onUnmounted(() => { tryOnUnmounted(() => {
handleAfterEnter(); handleAfterEnter();
stop(); stop();
}); });
return { return {
handleAfterEnter, handleAfterEnter,
on: { on: {
......
...@@ -49,7 +49,7 @@ const setting: ProjectConfig = { ...@@ -49,7 +49,7 @@ const setting: ProjectConfig = {
// 折叠菜单时候是否显示菜单名 // 折叠菜单时候是否显示菜单名
collapsedShowTitle: false, collapsedShowTitle: false,
// 是否可拖拽 // 是否可拖拽
hasDrag: true, hasDrag: false,
// 是否显示 // 是否显示
show: true, show: true,
// 是否显示搜索框 // 是否显示搜索框
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
import type { App } from 'vue'; import type { App } from 'vue';
import { Form, Input, Row, Col } from 'ant-design-vue'; import { Form, Input, Row, Col } from 'ant-design-vue';
import 'ant-design-vue/dist/antd.less'; import 'ant-design-vue/dist/antd.css';
import './spin'; import './spin';
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论