mirror of
https://github.com/vbenjs/vben-admin-thin-next.git
synced 2025-01-24 02:00:22 +08:00
perf: perf menu
This commit is contained in:
parent
74e62cbc71
commit
88f4a3f02a
@ -8,10 +8,10 @@
|
||||
:dropMenuList="localeList"
|
||||
:selectedKeys="selectedKeys"
|
||||
@menuEvent="handleMenuEvent"
|
||||
overlayClassName="app-locale-picker-overlay"
|
||||
:overlayClassName="`${prefixCls}-overlay`"
|
||||
>
|
||||
<span class="app-local-picker">
|
||||
<GlobalOutlined class="app-local-picker__icon" />
|
||||
<span :class="prefixCls">
|
||||
<GlobalOutlined :class="`${prefixCls}__icon`" />
|
||||
<span v-if="showText">{{ getLangText }}</span>
|
||||
</span>
|
||||
</Dropdown>
|
||||
@ -28,6 +28,7 @@
|
||||
import { LocaleType } from '/@/locales/types';
|
||||
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AppLocalPicker',
|
||||
@ -39,9 +40,12 @@
|
||||
reload: propTypes.bool,
|
||||
},
|
||||
setup(props) {
|
||||
const { localeList } = useLocaleSetting();
|
||||
const selectedKeys = ref<string[]>([]);
|
||||
|
||||
const { prefixCls } = useDesign('app-locale-picker');
|
||||
|
||||
const { localeList } = useLocaleSetting();
|
||||
|
||||
const { changeLocale, getLang } = useLocale();
|
||||
|
||||
const getLangText = computed(() => {
|
||||
@ -64,19 +68,22 @@
|
||||
toggleLocale(menu.event as string);
|
||||
}
|
||||
|
||||
return { localeList, handleMenuEvent, selectedKeys, getLangText };
|
||||
return { localeList, handleMenuEvent, selectedKeys, getLangText, prefixCls };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:global(.app-locale-picker-overlay) {
|
||||
@import (reference) '../../../design/index.less';
|
||||
@prefix-cls: ~'@{namespace}-app-locale-picker';
|
||||
|
||||
:global(.@{prefix-cls}-overlay) {
|
||||
.ant-dropdown-menu-item {
|
||||
min-width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
.app-local-picker {
|
||||
.@{prefix-cls} {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
@ -20,15 +20,17 @@
|
||||
expand: propTypes.bool,
|
||||
top: propTypes.bool,
|
||||
bottom: propTypes.bool,
|
||||
inset: propTypes.bool,
|
||||
},
|
||||
setup(props) {
|
||||
const getClass = computed(() => {
|
||||
const { expand, top, bottom } = props;
|
||||
const { expand, top, bottom, inset } = props;
|
||||
return [
|
||||
'base-arrow',
|
||||
{
|
||||
'base-arrow__active': expand,
|
||||
top,
|
||||
inset,
|
||||
bottom,
|
||||
},
|
||||
];
|
||||
@ -47,6 +49,10 @@
|
||||
transition: all 0.3s ease 0.1s;
|
||||
transform-origin: center center;
|
||||
|
||||
&.inset {
|
||||
line-height: 0px;
|
||||
}
|
||||
|
||||
&__active {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
@ -9,14 +9,15 @@ import {
|
||||
unref,
|
||||
reactive,
|
||||
watch,
|
||||
onMounted,
|
||||
ref,
|
||||
toRefs,
|
||||
ComputedRef,
|
||||
ref,
|
||||
CSSProperties,
|
||||
} from 'vue';
|
||||
import { Menu } from 'ant-design-vue';
|
||||
import MenuContent from './MenuContent';
|
||||
// import { ScrollContainer } from '/@/components/Container';
|
||||
// import { BasicArrow } from '/@/components/Basic';
|
||||
|
||||
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
||||
import { ThemeEnum } from '/@/enums/appEnum';
|
||||
@ -29,18 +30,20 @@ import { useRouter } from 'vue-router';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { getSlot } from '/@/utils/helper/tsxHelper';
|
||||
import { menuHasChildren } from './helper';
|
||||
|
||||
import { getCurrentParentPath } from '/@/router/menus';
|
||||
|
||||
import { basicProps } from './props';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { REDIRECT_NAME } from '/@/router/constant';
|
||||
import { tabStore } from '/@/store/modules/tab';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
export default defineComponent({
|
||||
name: 'BasicMenu',
|
||||
props: basicProps,
|
||||
emits: ['menuClick'],
|
||||
setup(props, { slots, emit }) {
|
||||
const currentParentPath = ref('');
|
||||
const isClickGo = ref(false);
|
||||
|
||||
const menuState = reactive<MenuState>({
|
||||
defaultSelectedKeys: [],
|
||||
@ -51,170 +54,184 @@ export default defineComponent({
|
||||
collapsedOpenKeys: [],
|
||||
});
|
||||
|
||||
const { getCollapsed } = useMenuSetting();
|
||||
const { prefixCls } = useDesign('basic-menu');
|
||||
|
||||
const { items, mode, accordion } = toRefs(props);
|
||||
|
||||
const { getCollapsed, getIsHorizontal, getTopMenuAlign, getSplit } = useMenuSetting();
|
||||
|
||||
const { currentRoute } = useRouter();
|
||||
|
||||
const { items, flatItems, mode, accordion } = toRefs(props);
|
||||
|
||||
const { handleOpenChange, resetKeys, setOpenKeys } = useOpenKeys(
|
||||
const { handleOpenChange, setOpenKeys, getOpenKeys } = useOpenKeys(
|
||||
menuState,
|
||||
items,
|
||||
flatItems,
|
||||
mode,
|
||||
accordion
|
||||
);
|
||||
|
||||
const getOpenKeys = computed(() => {
|
||||
return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys;
|
||||
});
|
||||
|
||||
// menu外层样式
|
||||
const getMenuWrapStyle = computed((): any => {
|
||||
const { showLogo } = props;
|
||||
let offset = 0;
|
||||
|
||||
if (showLogo) {
|
||||
offset += 46;
|
||||
}
|
||||
return {
|
||||
height: `calc(100% - ${offset}px)`,
|
||||
position: 'relative',
|
||||
overflowY: 'auto',
|
||||
};
|
||||
});
|
||||
|
||||
// 是否透明化左侧一级菜单
|
||||
const transparentMenuClass = computed(() => {
|
||||
const getMenuClass = computed(() => {
|
||||
const { type } = props;
|
||||
const { mode } = menuState;
|
||||
const cls: string[] = [];
|
||||
if (
|
||||
(type === MenuTypeEnum.TOP_MENU && mode === MenuModeEnum.HORIZONTAL) ||
|
||||
props.appendClass
|
||||
) {
|
||||
cls.push('basic-menu__sidebar-hor');
|
||||
}
|
||||
|
||||
if (!props.isHorizontal && appStore.getProjectConfig.menuSetting.split) {
|
||||
cls.push('basic-menu__second');
|
||||
}
|
||||
return cls;
|
||||
return [
|
||||
prefixCls,
|
||||
`justify-${unref(getTopMenuAlign)}`,
|
||||
{
|
||||
[`${prefixCls}--hide-title`]: !unref(showTitle),
|
||||
[`${prefixCls}--collapsed-show-title`]: props.collapsedShowTitle,
|
||||
[`${prefixCls}__second`]:
|
||||
!props.isHorizontal && appStore.getProjectConfig.menuSetting.split,
|
||||
[`${prefixCls}__sidebar-hor`]:
|
||||
type === MenuTypeEnum.TOP_MENU && mode === MenuModeEnum.HORIZONTAL,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const showTitle = computed(() => props.collapsedShowTitle && unref(getCollapsed));
|
||||
|
||||
const getInlineCollapseOptions = computed(() => {
|
||||
const isInline = props.mode === MenuModeEnum.INLINE;
|
||||
|
||||
const inlineCollapseOptions: { inlineCollapsed?: boolean } = {};
|
||||
if (isInline) {
|
||||
inlineCollapseOptions.inlineCollapsed = unref(getCollapsed);
|
||||
}
|
||||
return inlineCollapseOptions;
|
||||
});
|
||||
|
||||
const getWrapperStyle = computed(
|
||||
(): CSSProperties => {
|
||||
const isHorizontal = unref(getIsHorizontal);
|
||||
return {
|
||||
height: isHorizontal
|
||||
? `calc(100% + 1px)`
|
||||
: `calc(100% - ${props.showLogo ? '48px' : '0'})`,
|
||||
overflowY: isHorizontal ? 'hidden' : 'auto',
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => currentRoute.value.name,
|
||||
(name: string) => {
|
||||
if (name === REDIRECT_NAME) return;
|
||||
() => tabStore.getCurrentTab,
|
||||
() => {
|
||||
if (unref(currentRoute).name === REDIRECT_NAME) return;
|
||||
handleMenuChange();
|
||||
props.isHorizontal && appStore.getProjectConfig.menuSetting.split && getParentPath();
|
||||
unref(getSplit) && getParentPath();
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.items,
|
||||
() => {
|
||||
if (props.items) {
|
||||
handleMenuChange();
|
||||
}
|
||||
handleMenuChange();
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
getParentPath();
|
||||
|
||||
async function getParentPath() {
|
||||
const { appendClass } = props;
|
||||
if (!appendClass) return '';
|
||||
const parentPath = await getCurrentParentPath(unref(currentRoute).path);
|
||||
|
||||
currentParentPath.value = parentPath;
|
||||
}
|
||||
|
||||
async function handleMenuClick(menu: MenuType) {
|
||||
async function handleMenuClick({ key, keyPath }: { key: string; keyPath: string[] }) {
|
||||
const { beforeClickFn } = props;
|
||||
if (beforeClickFn && isFunction(beforeClickFn)) {
|
||||
const flag = await beforeClickFn(menu);
|
||||
const flag = await beforeClickFn(key);
|
||||
if (!flag) return;
|
||||
}
|
||||
emit('menuClick', menu);
|
||||
const { path } = menu;
|
||||
menuState.selectedKeys = [path];
|
||||
emit('menuClick', key);
|
||||
|
||||
isClickGo.value = true;
|
||||
menuState.openKeys = keyPath;
|
||||
menuState.selectedKeys = [key];
|
||||
}
|
||||
|
||||
function handleMenuChange() {
|
||||
const { flatItems } = props;
|
||||
if (!unref(flatItems) || flatItems.length === 0) return;
|
||||
const findMenu = flatItems.find((menu) => menu.path === unref(currentRoute).path);
|
||||
if (findMenu) {
|
||||
if (menuState.mode !== MenuModeEnum.HORIZONTAL) {
|
||||
setOpenKeys(findMenu);
|
||||
}
|
||||
menuState.selectedKeys = [findMenu.path];
|
||||
} else {
|
||||
resetKeys();
|
||||
if (unref(isClickGo)) {
|
||||
isClickGo.value = false;
|
||||
return;
|
||||
}
|
||||
const path = unref(currentRoute).path;
|
||||
if (menuState.mode !== MenuModeEnum.HORIZONTAL) {
|
||||
setOpenKeys(path);
|
||||
}
|
||||
menuState.selectedKeys = [path];
|
||||
}
|
||||
|
||||
// render menu item
|
||||
function renderMenuItem(menuList?: MenuType[], index = 1) {
|
||||
if (!menuList) return;
|
||||
const { appendClass } = props;
|
||||
const levelCls = `basic-menu-item__level${index} ${menuState.theme} `;
|
||||
return menuList.map((menu) => {
|
||||
if (!menu) {
|
||||
return null;
|
||||
}
|
||||
// function renderExpandIcon({ key }: { key: string }) {
|
||||
// const isOpen = getOpenKeys.value.includes(key);
|
||||
// const collapsed = unref(getCollapsed);
|
||||
// return (
|
||||
// <BasicArrow
|
||||
// expand={isOpen}
|
||||
// bottom
|
||||
// inset
|
||||
// class={[
|
||||
// `${prefixCls}__expand-icon`,
|
||||
// {
|
||||
// [`${prefixCls}__expand-icon--collapsed`]: collapsed,
|
||||
// },
|
||||
// ]}
|
||||
// />
|
||||
// );
|
||||
// }
|
||||
|
||||
const isAppendActiveCls =
|
||||
appendClass && index === 1 && menu.path === unref(currentParentPath);
|
||||
// 没有子节点
|
||||
if (!menuHasChildren(menu)) {
|
||||
return (
|
||||
<Menu.Item
|
||||
key={menu.path}
|
||||
class={`${levelCls}${isAppendActiveCls ? ' top-active-menu ' : ''}`}
|
||||
onClick={handleMenuClick.bind(null, menu)}
|
||||
>
|
||||
{() => [
|
||||
<MenuContent
|
||||
item={menu}
|
||||
level={index}
|
||||
isHorizontal={props.isHorizontal}
|
||||
showTitle={unref(showTitle)}
|
||||
/>,
|
||||
]}
|
||||
</Menu.Item>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Menu.SubMenu key={menu.path} class={levelCls}>
|
||||
{{
|
||||
title: () => [
|
||||
<MenuContent
|
||||
showTitle={unref(showTitle)}
|
||||
item={menu}
|
||||
level={index}
|
||||
isHorizontal={props.isHorizontal}
|
||||
/>,
|
||||
],
|
||||
default: () => renderMenuItem(menu.children, index + 1),
|
||||
}}
|
||||
</Menu.SubMenu>
|
||||
);
|
||||
});
|
||||
function renderItem(menu: MenuType, level = 1) {
|
||||
return !menuHasChildren(menu) ? renderMenuItem(menu, level) : renderSubMenu(menu, level);
|
||||
}
|
||||
|
||||
function renderMenuItem(menu: MenuType, level: number) {
|
||||
const { appendClass } = props;
|
||||
const isAppendActiveCls =
|
||||
appendClass && level === 1 && menu.path === unref(currentParentPath);
|
||||
const levelCls = [
|
||||
`${prefixCls}-item__level${level}`,
|
||||
` ${menuState.theme} `,
|
||||
{
|
||||
'top-active-menu': isAppendActiveCls,
|
||||
},
|
||||
];
|
||||
return (
|
||||
<Menu.Item key={menu.path} class={levelCls}>
|
||||
{() => [
|
||||
<MenuContent
|
||||
item={menu}
|
||||
showTitle={unref(showTitle)}
|
||||
isHorizontal={props.isHorizontal}
|
||||
/>,
|
||||
]}
|
||||
</Menu.Item>
|
||||
);
|
||||
}
|
||||
|
||||
function renderSubMenu(menu: MenuType, level: number) {
|
||||
const levelCls = `${prefixCls}-item__level${level} ${menuState.theme} `;
|
||||
return (
|
||||
<Menu.SubMenu key={menu.path} class={levelCls}>
|
||||
{{
|
||||
title: () => [
|
||||
<MenuContent
|
||||
showTitle={unref(showTitle)}
|
||||
item={menu}
|
||||
isHorizontal={props.isHorizontal}
|
||||
/>,
|
||||
],
|
||||
// expandIcon: renderExpandIcon,
|
||||
default: () => (menu.children || []).map((item) => renderItem(item, level + 1)),
|
||||
}}
|
||||
</Menu.SubMenu>
|
||||
);
|
||||
}
|
||||
|
||||
function renderMenu() {
|
||||
const isInline = props.mode === MenuModeEnum.INLINE;
|
||||
const { selectedKeys, defaultSelectedKeys, mode, theme } = menuState;
|
||||
|
||||
const inlineCollapsedObj = isInline
|
||||
? {
|
||||
inlineCollapsed: unref(getCollapsed),
|
||||
}
|
||||
: {};
|
||||
return (
|
||||
<Menu
|
||||
selectedKeys={selectedKeys}
|
||||
@ -224,36 +241,25 @@ export default defineComponent({
|
||||
inlineIndent={props.inlineIndent}
|
||||
theme={unref(theme)}
|
||||
onOpenChange={handleOpenChange}
|
||||
class={[
|
||||
'basic-menu',
|
||||
props.collapsedShowTitle && 'collapsed-show-title',
|
||||
...unref(transparentMenuClass),
|
||||
]}
|
||||
{...inlineCollapsedObj}
|
||||
class={unref(getMenuClass)}
|
||||
onClick={handleMenuClick}
|
||||
{...unref(getInlineCollapseOptions)}
|
||||
>
|
||||
{{
|
||||
default: () => renderMenuItem(props.items, 1),
|
||||
default: () => unref(items).map((item) => renderItem(item)),
|
||||
}}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
getParentPath();
|
||||
});
|
||||
|
||||
return () => {
|
||||
const { mode } = props;
|
||||
return mode === MenuModeEnum.HORIZONTAL ? (
|
||||
renderMenu()
|
||||
) : (
|
||||
<section class={[`basic-menu-wrap`, !unref(showTitle) && 'hide-title']}>
|
||||
{getSlot(slots, 'header')}
|
||||
|
||||
<section style={unref(getMenuWrapStyle)} class="basic-menu__content">
|
||||
return (
|
||||
<>
|
||||
{!unref(getIsHorizontal) && getSlot(slots, 'header')}
|
||||
<div class={`${prefixCls}-wrapper`} style={unref(getWrapperStyle)}>
|
||||
{renderMenu()}
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
},
|
||||
|
@ -1,11 +0,0 @@
|
||||
<template>
|
||||
<div> </div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
@ -1,9 +1,13 @@
|
||||
import type { Menu as MenuType } from '/@/router/types';
|
||||
import { computed, PropType, unref } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import { computed, unref } from 'vue';
|
||||
|
||||
import { defineComponent } from 'vue';
|
||||
import Icon from '/@/components/Icon/index';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
export default defineComponent({
|
||||
name: 'MenuContent',
|
||||
@ -12,12 +16,10 @@ export default defineComponent({
|
||||
type: Object as PropType<MenuType>,
|
||||
default: null,
|
||||
},
|
||||
|
||||
showTitle: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: true,
|
||||
},
|
||||
|
||||
level: {
|
||||
type: Number as PropType<number>,
|
||||
default: 0,
|
||||
@ -28,13 +30,32 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
const { prefixCls } = useDesign('basic-menu');
|
||||
|
||||
const getI18nName = computed(() => t(props.item?.name));
|
||||
|
||||
const getTagClass = computed(() => {
|
||||
const { item } = props;
|
||||
const { tag = {} } = item || {};
|
||||
const { dot, type = 'error' } = tag;
|
||||
return [
|
||||
`${prefixCls}__tag`,
|
||||
type,
|
||||
{
|
||||
dot,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const getNameClass = computed(() => {
|
||||
const { showTitle } = props;
|
||||
return { [`${prefixCls}--show-title`]: showTitle, [`${prefixCls}__name`]: !showTitle };
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: 渲染图标
|
||||
*/
|
||||
function renderIcon(icon: string) {
|
||||
function renderIcon(icon?: string) {
|
||||
return icon ? <Icon icon={icon} size={18} class="menu-item-icon" /> : null;
|
||||
}
|
||||
|
||||
@ -45,36 +66,30 @@ export default defineComponent({
|
||||
const { tag } = item;
|
||||
if (!tag) return null;
|
||||
|
||||
const { dot, content, type = 'error' } = tag;
|
||||
const { dot, content } = tag;
|
||||
if (!dot && !content) return null;
|
||||
const cls = ['basic-menu__tag'];
|
||||
|
||||
dot && cls.push('dot');
|
||||
type && cls.push(type);
|
||||
|
||||
return <span class={cls}>{dot ? '' : content}</span>;
|
||||
return <span class={unref(getTagClass)}>{dot ? '' : content}</span>;
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (!props.item) {
|
||||
const { item } = props;
|
||||
if (!item) {
|
||||
return null;
|
||||
}
|
||||
const { showTitle } = props;
|
||||
const { icon } = props.item;
|
||||
const { icon } = item;
|
||||
const name = unref(getI18nName);
|
||||
|
||||
const cls = showTitle ? ['show-title'] : ['basic-menu__name'];
|
||||
|
||||
return (
|
||||
<>
|
||||
{renderIcon(icon!)}
|
||||
<span class={`${prefixCls}__content-wrapper`}>
|
||||
{renderIcon(icon)}
|
||||
{
|
||||
<span class={[cls]}>
|
||||
<span class={unref(getNameClass)}>
|
||||
{name}
|
||||
{renderTag()}
|
||||
</span>
|
||||
}
|
||||
</>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
},
|
||||
|
@ -1,5 +1,7 @@
|
||||
@import (reference) '../../../design/index.less';
|
||||
|
||||
@basic-menu-prefix-cls: ~'@{namespace}-basic-menu';
|
||||
|
||||
.active-style() {
|
||||
color: @white;
|
||||
background: linear-gradient(
|
||||
@ -16,21 +18,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
.basic-menu {
|
||||
.@{basic-menu-prefix-cls} {
|
||||
width: 100%;
|
||||
|
||||
&-wrap {
|
||||
height: 100%;
|
||||
}
|
||||
// &__expand-icon {
|
||||
// position: absolute;
|
||||
// top: calc(50% - 6px);
|
||||
// right: 16px;
|
||||
// width: 10px;
|
||||
// transform-origin: none;
|
||||
|
||||
// span[role='img'] {
|
||||
// margin-right: 0;
|
||||
// font-size: 11px;
|
||||
// }
|
||||
|
||||
// &--collapsed {
|
||||
// opacity: 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// collapsed show title start
|
||||
.show-title {
|
||||
&--show-title {
|
||||
max-width: unset !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
&.collapsed-show-title.ant-menu-inline-collapsed {
|
||||
.basic-menu-item__level1 {
|
||||
&--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;
|
||||
}
|
||||
}
|
||||
|
||||
&--collapsed-show-title.ant-menu-inline-collapsed {
|
||||
.@{basic-menu-prefix-cls}-item__level1 {
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
@ -47,14 +76,23 @@
|
||||
& > li > .ant-menu-submenu-title {
|
||||
line-height: 24px;
|
||||
}
|
||||
.@{basic-menu-prefix-cls}__content-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
.@{basic-menu-prefix-cls}--show-title {
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-menu-item {
|
||||
transition: unset;
|
||||
}
|
||||
// .ant-menu-item {
|
||||
// transition: unset;
|
||||
// }
|
||||
|
||||
// scrollbar -s tart
|
||||
&__content {
|
||||
&-wrapper {
|
||||
/* 滚动槽 */
|
||||
&::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
@ -75,8 +113,20 @@
|
||||
background: @border-color-dark;
|
||||
}
|
||||
}
|
||||
|
||||
// scrollbar end
|
||||
|
||||
&-item__level1.light {
|
||||
&.top-active-menu {
|
||||
top: 0 !important;
|
||||
}
|
||||
|
||||
&.top-active-menu:not(.ant-menu-item-selected) {
|
||||
color: @primary-color;
|
||||
border-bottom: 3px solid @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&__sidebar-hor {
|
||||
// overflow: hidden;
|
||||
|
||||
@ -85,20 +135,13 @@
|
||||
border: 0;
|
||||
align-items: center;
|
||||
|
||||
.basic-menu-item__level1 {
|
||||
.@{basic-menu-prefix-cls}-item__level1 {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
&.ant-menu-light {
|
||||
.basic-menu-item__level1 {
|
||||
&.top-active-menu {
|
||||
color: @primary-color;
|
||||
border-bottom: 3px solid @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-menu-item {
|
||||
&.basic-menu-item__level1 {
|
||||
&.@{basic-menu-prefix-cls}-item__level1 {
|
||||
height: @header-height;
|
||||
line-height: @header-height;
|
||||
}
|
||||
@ -155,7 +198,7 @@
|
||||
background: @top-menu-active-bg-color;
|
||||
}
|
||||
|
||||
.basic-menu-item__level1 {
|
||||
.@{basic-menu-prefix-cls}-item__level1 {
|
||||
background: transparent;
|
||||
|
||||
&.top-active-menu {
|
||||
@ -172,7 +215,7 @@
|
||||
|
||||
.ant-menu-item,
|
||||
.ant-menu-submenu {
|
||||
&.basic-menu-item__level1,
|
||||
&.@{basic-menu-prefix-cls}-item__level1,
|
||||
.ant-menu-submenu-title {
|
||||
height: @header-height;
|
||||
line-height: @header-height;
|
||||
@ -182,17 +225,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.basic-menu__sidebar-hor).ant-menu-inline-collapsed {
|
||||
.basic-menu-item__level1 {
|
||||
&:not(.@{basic-menu-prefix-cls}__sidebar-hor).ant-menu-inline-collapsed {
|
||||
.@{basic-menu-prefix-cls}-item__level1 {
|
||||
> div {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-menu-dark:not(.basic-menu__sidebar-hor):not(.basic-menu__second) {
|
||||
&.ant-menu-dark:not(.@{basic-menu-prefix-cls}__sidebar-hor):not(.@{basic-menu-prefix-cls}__second) {
|
||||
// Reset menu item row height
|
||||
.ant-menu-item:not(.basic-menu-item__level1),
|
||||
.ant-menu-item:not(.@{basic-menu-prefix-cls}-item__level1),
|
||||
.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;
|
||||
@ -200,28 +243,28 @@
|
||||
line-height: @app-menu-item-height;
|
||||
}
|
||||
|
||||
.ant-menu-item.basic-menu-item__level1 {
|
||||
.ant-menu-item.@{basic-menu-prefix-cls}-item__level1 {
|
||||
height: @app-menu-item-height;
|
||||
line-height: @app-menu-item-height;
|
||||
}
|
||||
}
|
||||
|
||||
// 层级样式
|
||||
&.ant-menu-dark:not(.basic-menu__sidebar-hor) {
|
||||
overflow-x: hidden;
|
||||
&.ant-menu-dark:not(.@{basic-menu-prefix-cls}__sidebar-hor) {
|
||||
overflow: hidden;
|
||||
background: @sider-dark-bg-color;
|
||||
.active-menu-style();
|
||||
|
||||
.menu-item-icon.app-iconify {
|
||||
display: inline-block !important;
|
||||
}
|
||||
// .menu-item-icon.app-iconify {
|
||||
// display: inline-block !important;
|
||||
// }
|
||||
|
||||
.ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1,
|
||||
.ant-menu-submenu-selected.basic-menu-menu-item__level1 {
|
||||
.ant-menu-item.ant-menu-item-selected.@{basic-menu-prefix-cls}-menu-item__level1,
|
||||
.ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 {
|
||||
color: @white;
|
||||
}
|
||||
|
||||
.basic-menu-item__level1 {
|
||||
.@{basic-menu-prefix-cls}-item__level1 {
|
||||
background-color: @sider-dark-bg-color;
|
||||
|
||||
> .ant-menu-sub > li {
|
||||
@ -229,12 +272,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.basic-menu-item__level2:not(.ant-menu-item-selected),
|
||||
.@{basic-menu-prefix-cls}-item__level2:not(.ant-menu-item-selected),
|
||||
.ant-menu-sub {
|
||||
background-color: @sider-dark-lighten-1-bg-color;
|
||||
}
|
||||
|
||||
.basic-menu-item__level3:not(.ant-menu-item-selected) {
|
||||
.@{basic-menu-prefix-cls}-item__level3:not(.ant-menu-item-selected) {
|
||||
background-color: @sider-dark-lighten-2-bg-color;
|
||||
|
||||
.ant-menu-item {
|
||||
@ -257,35 +300,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-menu-light:not(.basic-menu__sidebar-hor) {
|
||||
overflow-x: hidden;
|
||||
&.ant-menu-light:not(.@{basic-menu-prefix-cls}__sidebar-hor) {
|
||||
overflow: hidden;
|
||||
border-right: none;
|
||||
|
||||
.menu-item-icon.app-iconify {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
// .ant-menu-item-selected {
|
||||
// background: fade(@primary-color, 18%);
|
||||
// .menu-item-icon.app-iconify {
|
||||
// display: inline-block !important;
|
||||
// }
|
||||
|
||||
.ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1,
|
||||
.ant-menu-submenu-selected.basic-menu-menu-item__level1 {
|
||||
.ant-menu-item.ant-menu-item-selected.@{basic-menu-prefix-cls}-menu-item__level1,
|
||||
.ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
// 关键字的颜色
|
||||
&__keyword {
|
||||
color: lighten(@primary-color, 20%);
|
||||
}
|
||||
|
||||
// 激活的子菜单样式
|
||||
.ant-menu-item.ant-menu-item-selected {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&.basic-menu__second.ant-menu-inline-collapsed:not(.basic-menu__sidebar-hor) {
|
||||
&.@{basic-menu-prefix-cls}__second.ant-menu-inline-collapsed:not(.@{basic-menu-prefix-cls}__sidebar-hor) {
|
||||
// Reset menu item row height
|
||||
.ant-menu-item,
|
||||
.ant-menu-sub.ant-menu-inline > .ant-menu-item,
|
||||
@ -298,26 +332,40 @@
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.@{basic-menu-prefix-cls}__tag {
|
||||
position: absolute;
|
||||
top: calc(50% - 8px);
|
||||
right: 30px;
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
margin-right: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
|
||||
// 触发器样式
|
||||
.ant-layout-sider {
|
||||
&-dark {
|
||||
.ant-layout-sider-trigger {
|
||||
color: darken(@white, 25%);
|
||||
background: @trigger-dark-bg-color;
|
||||
|
||||
&:hover {
|
||||
color: @white;
|
||||
background: @trigger-dark-hover-bg-color;
|
||||
}
|
||||
&.dot {
|
||||
top: calc(50% - 4px);
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
padding: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
&-light {
|
||||
.ant-layout-sider-trigger {
|
||||
color: @text-color-base;
|
||||
border-top: 1px solid @border-color-light;
|
||||
&.primary {
|
||||
background: @primary-color;
|
||||
}
|
||||
|
||||
&.error {
|
||||
background: @error-color;
|
||||
}
|
||||
|
||||
&.success {
|
||||
background: @success-color;
|
||||
}
|
||||
|
||||
&.warn {
|
||||
background: @warning-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -332,71 +380,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// collapsed show title end
|
||||
.ant-menu-item,
|
||||
.ant-menu-submenu-title {
|
||||
> .basic-menu__name {
|
||||
> .@{basic-menu-prefix-cls}__name {
|
||||
width: 100%;
|
||||
|
||||
.basic-menu__tag {
|
||||
.@{basic-menu-prefix-cls}__tag {
|
||||
float: right;
|
||||
margin-top: @app-menu-item-height / 2;
|
||||
transform: translate(0%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.basic-menu__tag {
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
margin-right: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
|
||||
&.dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
padding: 0;
|
||||
margin-top: 21px !important;
|
||||
margin-bottom: 2px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
background: @primary-color;
|
||||
}
|
||||
|
||||
&.error {
|
||||
background: @error-color;
|
||||
}
|
||||
|
||||
&.success {
|
||||
background: @success-color;
|
||||
}
|
||||
|
||||
&.warn {
|
||||
background: @warning-color;
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,11 @@ export const basicProps = {
|
||||
type: Array as PropType<Menu[]>,
|
||||
default: () => [],
|
||||
},
|
||||
flatItems: {
|
||||
type: Array as PropType<Menu[]>,
|
||||
default: () => [],
|
||||
},
|
||||
appendClass: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
|
||||
collapsedShowTitle: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
@ -31,6 +28,10 @@ export const basicProps = {
|
||||
type: String as PropType<MenuModeEnum>,
|
||||
default: MenuModeEnum.INLINE,
|
||||
},
|
||||
showLogo: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String as PropType<MenuTypeEnum>,
|
||||
default: MenuTypeEnum.MIX,
|
||||
@ -39,10 +40,6 @@ export const basicProps = {
|
||||
type: String as PropType<string>,
|
||||
default: ThemeEnum.DARK,
|
||||
},
|
||||
showLogo: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
inlineCollapsed: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
@ -57,7 +54,6 @@ export const basicProps = {
|
||||
default: true,
|
||||
},
|
||||
beforeClickFn: {
|
||||
type: Function as PropType<Fn>,
|
||||
default: null,
|
||||
type: Function as PropType<(key: string) => Promise<boolean>>,
|
||||
},
|
||||
};
|
||||
|
@ -1,34 +1,35 @@
|
||||
import { MenuModeEnum } from '/@/enums/menuEnum';
|
||||
import type { Menu as MenuType } from '/@/router/types';
|
||||
import type { MenuState } from './types';
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import { computed, Ref, toRaw } from 'vue';
|
||||
|
||||
import { unref } from 'vue';
|
||||
import { getAllParentPath } from '/@/router/helper/menuHelper';
|
||||
import { es6Unique } from '/@/utils';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { getAllParentPath } from '/@/router/helper/menuHelper';
|
||||
|
||||
export function useOpenKeys(
|
||||
menuState: MenuState,
|
||||
menus: Ref<MenuType[]>,
|
||||
flatMenusRef: Ref<MenuType[]>,
|
||||
mode: Ref<MenuModeEnum>,
|
||||
accordion: Ref<boolean>
|
||||
) {
|
||||
const { getCollapsed } = useMenuSetting();
|
||||
|
||||
function setOpenKeys(menu: MenuType) {
|
||||
const flatMenus = unref(flatMenusRef);
|
||||
function setOpenKeys(path: string) {
|
||||
const menuList = toRaw(menus.value);
|
||||
if (!unref(accordion)) {
|
||||
menuState.openKeys = es6Unique([
|
||||
...menuState.openKeys,
|
||||
...getAllParentPath(flatMenus, menu.path),
|
||||
]);
|
||||
menuState.openKeys = es6Unique([...menuState.openKeys, ...getAllParentPath(menuList, path)]);
|
||||
} else {
|
||||
menuState.openKeys = getAllParentPath(flatMenus, menu.path);
|
||||
menuState.openKeys = getAllParentPath(menuList, path);
|
||||
}
|
||||
}
|
||||
|
||||
const getOpenKeys = computed(() => {
|
||||
return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys;
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: 重置值
|
||||
*/
|
||||
@ -59,5 +60,5 @@ export function useOpenKeys(
|
||||
}
|
||||
}
|
||||
}
|
||||
return { setOpenKeys, resetKeys, handleOpenChange };
|
||||
return { setOpenKeys, resetKeys, getOpenKeys, handleOpenChange };
|
||||
}
|
||||
|
@ -11,76 +11,76 @@ import { useFullContent } from '/@/hooks/web/useFullContent';
|
||||
|
||||
import { MenuModeEnum } from '/@/enums/menuEnum';
|
||||
|
||||
const { getFullContent } = useFullContent();
|
||||
const { getShowMultipleTab } = useMultipleTabSetting();
|
||||
const {
|
||||
getMenuMode,
|
||||
getSplit,
|
||||
getShowHeaderTrigger,
|
||||
getIsSidebarType,
|
||||
getIsTopMenu,
|
||||
} = useMenuSetting();
|
||||
const { getShowBreadCrumb, getShowLogo } = useRootSetting();
|
||||
|
||||
const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader));
|
||||
|
||||
const getShowFullHeaderRef = computed(() => {
|
||||
return (
|
||||
!unref(getFullContent) &&
|
||||
unref(getShowMixHeaderRef) &&
|
||||
unref(getShowHeader) &&
|
||||
!unref(getIsTopMenu)
|
||||
);
|
||||
});
|
||||
|
||||
const getShowInsetHeaderRef = computed(() => {
|
||||
const need = !unref(getFullContent) && unref(getShowHeader);
|
||||
return (need && !unref(getShowMixHeaderRef)) || (need && unref(getIsTopMenu));
|
||||
});
|
||||
|
||||
// Get header configuration
|
||||
const getHeaderSetting = computed(() => appStore.getProjectConfig.headerSetting);
|
||||
|
||||
const getShowDoc = computed(() => unref(getHeaderSetting).showDoc);
|
||||
|
||||
const getHeaderTheme = computed(() => unref(getHeaderSetting).theme);
|
||||
|
||||
const getShowHeader = computed(() => unref(getHeaderSetting).show);
|
||||
|
||||
const getFixed = computed(() => unref(getHeaderSetting).fixed);
|
||||
|
||||
const getHeaderBgColor = computed(() => unref(getHeaderSetting).bgColor);
|
||||
|
||||
const getShowRedo = computed(() => unref(getHeaderSetting).showRedo && unref(getShowMultipleTab));
|
||||
|
||||
const getUseLockPage = computed(() => unref(getHeaderSetting).useLockPage);
|
||||
|
||||
const getShowFullScreen = computed(() => unref(getHeaderSetting).showFullScreen);
|
||||
|
||||
const getShowNotice = computed(() => unref(getHeaderSetting).showNotice);
|
||||
|
||||
const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef));
|
||||
|
||||
const getShowBread = computed(() => {
|
||||
return (
|
||||
unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit)
|
||||
);
|
||||
});
|
||||
|
||||
const getShowHeaderLogo = computed(() => {
|
||||
return unref(getShowLogo) && !unref(getIsSidebarType);
|
||||
});
|
||||
|
||||
const getShowContent = computed(() => {
|
||||
return unref(getShowBread) || unref(getShowHeaderTrigger);
|
||||
});
|
||||
|
||||
// Set header configuration
|
||||
function setHeaderSetting(headerSetting: Partial<HeaderSetting>): void {
|
||||
appStore.commitProjectConfigState({ headerSetting });
|
||||
}
|
||||
|
||||
export function useHeaderSetting() {
|
||||
const { getFullContent } = useFullContent();
|
||||
const { getShowMultipleTab } = useMultipleTabSetting();
|
||||
const {
|
||||
getMenuMode,
|
||||
getSplit,
|
||||
getShowHeaderTrigger,
|
||||
getIsSidebarType,
|
||||
getIsTopMenu,
|
||||
} = useMenuSetting();
|
||||
const { getShowBreadCrumb, getShowLogo } = useRootSetting();
|
||||
|
||||
const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader));
|
||||
|
||||
const getShowFullHeaderRef = computed(() => {
|
||||
return (
|
||||
!unref(getFullContent) &&
|
||||
unref(getShowMixHeaderRef) &&
|
||||
unref(getShowHeader) &&
|
||||
!unref(getIsTopMenu)
|
||||
);
|
||||
});
|
||||
|
||||
const getShowInsetHeaderRef = computed(() => {
|
||||
const need = !unref(getFullContent) && unref(getShowHeader);
|
||||
return (need && !unref(getShowMixHeaderRef)) || (need && unref(getIsTopMenu));
|
||||
});
|
||||
|
||||
// Get header configuration
|
||||
const getHeaderSetting = computed(() => appStore.getProjectConfig.headerSetting);
|
||||
|
||||
const getShowDoc = computed(() => unref(getHeaderSetting).showDoc);
|
||||
|
||||
const getHeaderTheme = computed(() => unref(getHeaderSetting).theme);
|
||||
|
||||
const getShowHeader = computed(() => unref(getHeaderSetting).show);
|
||||
|
||||
const getFixed = computed(() => unref(getHeaderSetting).fixed);
|
||||
|
||||
const getHeaderBgColor = computed(() => unref(getHeaderSetting).bgColor);
|
||||
|
||||
const getShowRedo = computed(() => unref(getHeaderSetting).showRedo && unref(getShowMultipleTab));
|
||||
|
||||
const getUseLockPage = computed(() => unref(getHeaderSetting).useLockPage);
|
||||
|
||||
const getShowFullScreen = computed(() => unref(getHeaderSetting).showFullScreen);
|
||||
|
||||
const getShowNotice = computed(() => unref(getHeaderSetting).showNotice);
|
||||
|
||||
const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef));
|
||||
|
||||
const getShowBread = computed(() => {
|
||||
return (
|
||||
unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit)
|
||||
);
|
||||
});
|
||||
|
||||
const getShowHeaderLogo = computed(() => {
|
||||
return unref(getShowLogo) && !unref(getIsSidebarType);
|
||||
});
|
||||
|
||||
const getShowContent = computed(() => {
|
||||
return unref(getShowBread) || unref(getShowHeaderTrigger);
|
||||
});
|
||||
|
||||
// Set header configuration
|
||||
function setHeaderSetting(headerSetting: Partial<HeaderSetting>): void {
|
||||
appStore.commitProjectConfigState({ headerSetting });
|
||||
}
|
||||
|
||||
return {
|
||||
setHeaderSetting,
|
||||
|
||||
|
@ -6,26 +6,26 @@ import { appStore } from '/@/store/modules/app';
|
||||
import getProjectSetting from '/@/settings/projectSetting';
|
||||
import { localeList } from '/@/locales';
|
||||
|
||||
// Get locale configuration
|
||||
const getLocale = computed(() => appStore.getProjectConfig.locale || getProjectSetting.locale);
|
||||
|
||||
// get current language
|
||||
const getLang = computed(() => unref(getLocale).lang);
|
||||
|
||||
// get Available Locales
|
||||
const getAvailableLocales = computed((): string[] => unref(getLocale).availableLocales);
|
||||
|
||||
// get Fallback Locales
|
||||
const getFallbackLocale = computed((): string => unref(getLocale).fallback);
|
||||
|
||||
const getShowLocale = computed(() => unref(getLocale).show);
|
||||
|
||||
// Set locale configuration
|
||||
function setLocale(locale: Partial<LocaleSetting>): void {
|
||||
appStore.commitProjectConfigState({ locale });
|
||||
}
|
||||
|
||||
export function useLocaleSetting() {
|
||||
// Get locale configuration
|
||||
const getLocale = computed(() => appStore.getProjectConfig.locale || getProjectSetting.locale);
|
||||
|
||||
// get current language
|
||||
const getLang = computed(() => unref(getLocale).lang);
|
||||
|
||||
// get Available Locales
|
||||
const getAvailableLocales = computed((): string[] => unref(getLocale).availableLocales);
|
||||
|
||||
// get Fallback Locales
|
||||
const getFallbackLocale = computed((): string => unref(getLocale).fallback);
|
||||
|
||||
const getShowLocale = computed(() => unref(getLocale).show);
|
||||
|
||||
// Set locale configuration
|
||||
function setLocale(locale: Partial<LocaleSetting>): void {
|
||||
appStore.commitProjectConfigState({ locale });
|
||||
}
|
||||
|
||||
return {
|
||||
getLocale,
|
||||
getLang,
|
||||
|
@ -7,89 +7,89 @@ import { appStore } from '/@/store/modules/app';
|
||||
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
|
||||
import { MenuModeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
|
||||
|
||||
// Get menu configuration
|
||||
const getMenuSetting = computed(() => appStore.getProjectConfig.menuSetting);
|
||||
|
||||
const getCollapsed = computed(() => unref(getMenuSetting).collapsed);
|
||||
|
||||
const getMenuType = computed(() => unref(getMenuSetting).type);
|
||||
|
||||
const getMenuMode = computed(() => unref(getMenuSetting).mode);
|
||||
|
||||
const getMenuFixed = computed(() => unref(getMenuSetting).fixed);
|
||||
|
||||
const getShowMenu = computed(() => unref(getMenuSetting).show);
|
||||
|
||||
const getMenuHidden = computed(() => unref(getMenuSetting).hidden);
|
||||
|
||||
const getMenuWidth = computed(() => unref(getMenuSetting).menuWidth);
|
||||
|
||||
const getTrigger = computed(() => unref(getMenuSetting).trigger);
|
||||
|
||||
const getMenuTheme = computed(() => unref(getMenuSetting).theme);
|
||||
|
||||
const getSplit = computed(() => unref(getMenuSetting).split);
|
||||
|
||||
const getMenuBgColor = computed(() => unref(getMenuSetting).bgColor);
|
||||
|
||||
const getCanDrag = computed(() => unref(getMenuSetting).canDrag);
|
||||
|
||||
const getAccordion = computed(() => unref(getMenuSetting).accordion);
|
||||
|
||||
const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle);
|
||||
|
||||
const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign);
|
||||
|
||||
const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR);
|
||||
|
||||
const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU);
|
||||
|
||||
const getShowTopMenu = computed(() => {
|
||||
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit);
|
||||
});
|
||||
|
||||
const getShowHeaderTrigger = computed(() => {
|
||||
if (
|
||||
unref(getMenuType) === MenuTypeEnum.TOP_MENU ||
|
||||
!unref(getShowMenu) ||
|
||||
!unref(getMenuHidden)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return unref(getTrigger) === TriggerEnum.HEADER;
|
||||
});
|
||||
|
||||
const getIsHorizontal = computed(() => {
|
||||
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL;
|
||||
});
|
||||
|
||||
const getRealWidth = computed(() => {
|
||||
return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth);
|
||||
});
|
||||
|
||||
const getMiniWidthNumber = computed(() => {
|
||||
const { collapsedShowTitle } = unref(getMenuSetting);
|
||||
return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
|
||||
});
|
||||
|
||||
const getCalcContentWidth = computed(() => {
|
||||
const width = unref(getIsTopMenu) || !unref(getShowMenu) ? 0 : unref(getRealWidth);
|
||||
return `calc(100% - ${unref(width)}px)`;
|
||||
});
|
||||
|
||||
// Set menu configuration
|
||||
function setMenuSetting(menuSetting: Partial<MenuSetting>): void {
|
||||
appStore.commitProjectConfigState({ menuSetting });
|
||||
}
|
||||
|
||||
function toggleCollapsed() {
|
||||
setMenuSetting({
|
||||
collapsed: !unref(getCollapsed),
|
||||
});
|
||||
}
|
||||
|
||||
export function useMenuSetting() {
|
||||
// Get menu configuration
|
||||
const getMenuSetting = computed(() => appStore.getProjectConfig.menuSetting);
|
||||
|
||||
const getCollapsed = computed(() => unref(getMenuSetting).collapsed);
|
||||
|
||||
const getMenuType = computed(() => unref(getMenuSetting).type);
|
||||
|
||||
const getMenuMode = computed(() => unref(getMenuSetting).mode);
|
||||
|
||||
const getMenuFixed = computed(() => unref(getMenuSetting).fixed);
|
||||
|
||||
const getShowMenu = computed(() => unref(getMenuSetting).show);
|
||||
|
||||
const getMenuHidden = computed(() => unref(getMenuSetting).hidden);
|
||||
|
||||
const getMenuWidth = computed(() => unref(getMenuSetting).menuWidth);
|
||||
|
||||
const getTrigger = computed(() => unref(getMenuSetting).trigger);
|
||||
|
||||
const getMenuTheme = computed(() => unref(getMenuSetting).theme);
|
||||
|
||||
const getSplit = computed(() => unref(getMenuSetting).split);
|
||||
|
||||
const getMenuBgColor = computed(() => unref(getMenuSetting).bgColor);
|
||||
|
||||
const getCanDrag = computed(() => unref(getMenuSetting).canDrag);
|
||||
|
||||
const getAccordion = computed(() => unref(getMenuSetting).accordion);
|
||||
|
||||
const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle);
|
||||
|
||||
const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign);
|
||||
|
||||
const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR);
|
||||
|
||||
const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU);
|
||||
|
||||
const getShowTopMenu = computed(() => {
|
||||
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit);
|
||||
});
|
||||
|
||||
const getShowHeaderTrigger = computed(() => {
|
||||
if (
|
||||
unref(getMenuType) === MenuTypeEnum.TOP_MENU ||
|
||||
!unref(getShowMenu) ||
|
||||
!unref(getMenuHidden)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return unref(getTrigger) === TriggerEnum.HEADER;
|
||||
});
|
||||
|
||||
const getIsHorizontal = computed(() => {
|
||||
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL;
|
||||
});
|
||||
|
||||
const getRealWidth = computed(() => {
|
||||
return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth);
|
||||
});
|
||||
|
||||
const getMiniWidthNumber = computed(() => {
|
||||
const { collapsedShowTitle } = unref(getMenuSetting);
|
||||
return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
|
||||
});
|
||||
|
||||
const getCalcContentWidth = computed(() => {
|
||||
const width = unref(getIsTopMenu) || !unref(getShowMenu) ? 0 : unref(getRealWidth);
|
||||
return `calc(100% - ${unref(width)}px)`;
|
||||
});
|
||||
|
||||
// Set menu configuration
|
||||
function setMenuSetting(menuSetting: Partial<MenuSetting>): void {
|
||||
appStore.commitProjectConfigState({ menuSetting });
|
||||
}
|
||||
|
||||
function toggleCollapsed() {
|
||||
setMenuSetting({
|
||||
collapsed: !unref(getCollapsed),
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
setMenuSetting,
|
||||
|
||||
|
@ -4,17 +4,17 @@ import { computed, unref } from 'vue';
|
||||
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
|
||||
const getMultipleTabSetting = computed(() => appStore.getProjectConfig.multiTabsSetting);
|
||||
|
||||
const getShowMultipleTab = computed(() => unref(getMultipleTabSetting).show);
|
||||
|
||||
const getShowQuick = computed(() => unref(getMultipleTabSetting).showQuick);
|
||||
|
||||
function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) {
|
||||
appStore.commitProjectConfigState({ multiTabsSetting });
|
||||
}
|
||||
|
||||
export function useMultipleTabSetting() {
|
||||
const getMultipleTabSetting = computed(() => appStore.getProjectConfig.multiTabsSetting);
|
||||
|
||||
const getShowMultipleTab = computed(() => unref(getMultipleTabSetting).show);
|
||||
|
||||
const getShowQuick = computed(() => unref(getMultipleTabSetting).showQuick);
|
||||
|
||||
function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) {
|
||||
appStore.commitProjectConfigState({ multiTabsSetting });
|
||||
}
|
||||
|
||||
return {
|
||||
setMultipleTabSetting,
|
||||
|
||||
|
@ -9,47 +9,48 @@ type RootSetting = Omit<
|
||||
ProjectConfig,
|
||||
'locale' | 'headerSetting' | 'menuSetting' | 'multiTabsSetting'
|
||||
>;
|
||||
|
||||
const getRootSetting = computed((): RootSetting => appStore.getProjectConfig);
|
||||
|
||||
const getPageLoading = computed(() => appStore.getPageLoading);
|
||||
|
||||
const getOpenKeepAlive = computed(() => unref(getRootSetting).openKeepAlive);
|
||||
|
||||
const getCanEmbedIFramePage = computed(() => unref(getRootSetting).canEmbedIFramePage);
|
||||
|
||||
const getPermissionMode = computed(() => unref(getRootSetting).permissionMode);
|
||||
|
||||
const getShowLogo = computed(() => unref(getRootSetting).showLogo);
|
||||
|
||||
const getContentMode = computed(() => unref(getRootSetting).contentMode);
|
||||
|
||||
const getUseOpenBackTop = computed(() => unref(getRootSetting).useOpenBackTop);
|
||||
|
||||
const getShowSettingButton = computed(() => unref(getRootSetting).showSettingButton);
|
||||
|
||||
const getUseErrorHandle = computed(() => unref(getRootSetting).useErrorHandle);
|
||||
|
||||
const getShowFooter = computed(() => unref(getRootSetting).showFooter);
|
||||
|
||||
const getShowBreadCrumb = computed(() => unref(getRootSetting).showBreadCrumb);
|
||||
|
||||
const getShowBreadCrumbIcon = computed(() => unref(getRootSetting).showBreadCrumbIcon);
|
||||
|
||||
const getFullContent = computed(() => unref(getRootSetting).fullContent);
|
||||
|
||||
const getColorWeak = computed(() => unref(getRootSetting).colorWeak);
|
||||
|
||||
const getGrayMode = computed(() => unref(getRootSetting).grayMode);
|
||||
|
||||
const getLayoutContentMode = computed(() =>
|
||||
unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED
|
||||
);
|
||||
|
||||
function setRootSetting(setting: Partial<RootSetting>) {
|
||||
appStore.commitProjectConfigState(setting);
|
||||
}
|
||||
|
||||
export function useRootSetting() {
|
||||
const getRootSetting = computed((): RootSetting => appStore.getProjectConfig);
|
||||
|
||||
const getPageLoading = computed(() => appStore.getPageLoading);
|
||||
|
||||
const getOpenKeepAlive = computed(() => unref(getRootSetting).openKeepAlive);
|
||||
|
||||
const getCanEmbedIFramePage = computed(() => unref(getRootSetting).canEmbedIFramePage);
|
||||
|
||||
const getPermissionMode = computed(() => unref(getRootSetting).permissionMode);
|
||||
|
||||
const getShowLogo = computed(() => unref(getRootSetting).showLogo);
|
||||
|
||||
const getContentMode = computed(() => unref(getRootSetting).contentMode);
|
||||
|
||||
const getUseOpenBackTop = computed(() => unref(getRootSetting).useOpenBackTop);
|
||||
|
||||
const getShowSettingButton = computed(() => unref(getRootSetting).showSettingButton);
|
||||
|
||||
const getUseErrorHandle = computed(() => unref(getRootSetting).useErrorHandle);
|
||||
|
||||
const getShowFooter = computed(() => unref(getRootSetting).showFooter);
|
||||
|
||||
const getShowBreadCrumb = computed(() => unref(getRootSetting).showBreadCrumb);
|
||||
|
||||
const getShowBreadCrumbIcon = computed(() => unref(getRootSetting).showBreadCrumbIcon);
|
||||
|
||||
const getFullContent = computed(() => unref(getRootSetting).fullContent);
|
||||
|
||||
const getColorWeak = computed(() => unref(getRootSetting).colorWeak);
|
||||
|
||||
const getGrayMode = computed(() => unref(getRootSetting).grayMode);
|
||||
|
||||
const getLayoutContentMode = computed(() =>
|
||||
unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED
|
||||
);
|
||||
|
||||
function setRootSetting(setting: Partial<RootSetting>) {
|
||||
appStore.commitProjectConfigState(setting);
|
||||
}
|
||||
|
||||
return {
|
||||
setRootSetting,
|
||||
|
||||
|
@ -4,23 +4,23 @@ import { computed, unref } from 'vue';
|
||||
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
|
||||
const getTransitionSetting = computed(() => appStore.getProjectConfig.transitionSetting);
|
||||
|
||||
const getEnableTransition = computed(() => unref(getTransitionSetting)?.enable);
|
||||
|
||||
const getOpenNProgress = computed(() => unref(getTransitionSetting)?.openNProgress);
|
||||
|
||||
const getOpenPageLoading = computed((): boolean => {
|
||||
return !!unref(getTransitionSetting)?.openPageLoading;
|
||||
});
|
||||
|
||||
const getBasicTransition = computed(() => unref(getTransitionSetting)?.basicTransition);
|
||||
|
||||
function setTransitionSetting(transitionSetting: Partial<TransitionSetting>) {
|
||||
appStore.commitProjectConfigState({ transitionSetting });
|
||||
}
|
||||
|
||||
export function useTransitionSetting() {
|
||||
const getTransitionSetting = computed(() => appStore.getProjectConfig.transitionSetting);
|
||||
|
||||
const getEnableTransition = computed(() => unref(getTransitionSetting)?.enable);
|
||||
|
||||
const getOpenNProgress = computed(() => unref(getTransitionSetting)?.openNProgress);
|
||||
|
||||
const getOpenPageLoading = computed((): boolean => {
|
||||
return !!unref(getTransitionSetting)?.openPageLoading;
|
||||
});
|
||||
|
||||
const getBasicTransition = computed(() => unref(getTransitionSetting)?.basicTransition);
|
||||
|
||||
function setTransitionSetting(transitionSetting: Partial<TransitionSetting>) {
|
||||
appStore.commitProjectConfigState({ transitionSetting });
|
||||
}
|
||||
|
||||
return {
|
||||
setTransitionSetting,
|
||||
|
||||
|
@ -1,18 +1,21 @@
|
||||
import { useAppProviderContext } from '/@/components/Application';
|
||||
import { computed } from 'vue';
|
||||
// import { useCssModule, reactive } from 'vue';
|
||||
// import { computed } from 'vue';
|
||||
// import { lowerFirst } from 'lodash-es';
|
||||
export function useDesign(scope: string) {
|
||||
const values = useAppProviderContext();
|
||||
// const style = cssModule ? useCssModule() : {};
|
||||
// const $style = cssModule ? useCssModule() : {};
|
||||
|
||||
// const style: Record<string, string> = {};
|
||||
// if (cssModule) {
|
||||
// Object.keys(style).forEach((key) => {
|
||||
// const moduleCls = style[key];
|
||||
// style[key] = `${cls}-${moduleCls}`;
|
||||
// Object.keys($style).forEach((key) => {
|
||||
// // const moduleCls = $style[key];
|
||||
// const k = key.replace(new RegExp(`^${values.prefixCls}-?`, 'ig'), '');
|
||||
// style[lowerFirst(k)] = $style[key];
|
||||
// });
|
||||
// }
|
||||
return {
|
||||
prefixCls: computed(() => `${values.prefixCls}-${scope}`),
|
||||
// prefixCls: computed(() => `${values.prefixCls}-${scope}`),
|
||||
prefixCls: `${values.prefixCls}-${scope}`,
|
||||
prefixVar: values.prefixCls,
|
||||
// style,
|
||||
};
|
||||
|
@ -2,12 +2,12 @@ import { computed, unref } from 'vue';
|
||||
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
|
||||
import { useRouter } from 'vue-router';
|
||||
import router from '/@/router';
|
||||
/**
|
||||
* @description: Full screen display content
|
||||
*/
|
||||
export const useFullContent = () => {
|
||||
const { currentRoute } = useRouter();
|
||||
const { currentRoute } = router;
|
||||
|
||||
// Whether to display the content in full screen without displaying the menu
|
||||
const getFullContent = computed(() => {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
import type { RouteLocationRaw } from 'vue-router';
|
||||
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
@ -11,7 +10,6 @@ export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEn
|
||||
|
||||
function handleError(e: Error) {
|
||||
console.error(e);
|
||||
appStore.commitPageLoadingState(false);
|
||||
}
|
||||
|
||||
// page switch
|
||||
|
@ -80,13 +80,7 @@ export default defineComponent({
|
||||
const { refreshPage } = useTabs();
|
||||
const { t } = useI18n();
|
||||
|
||||
const {
|
||||
getShowTopMenu,
|
||||
getShowHeaderTrigger,
|
||||
getSplit,
|
||||
getTopMenuAlign,
|
||||
getIsHorizontal,
|
||||
} = useMenuSetting();
|
||||
const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsHorizontal } = useMenuSetting();
|
||||
|
||||
const { getShowLocale } = useLocaleSetting();
|
||||
const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting();
|
||||
@ -184,7 +178,7 @@ export default defineComponent({
|
||||
{/* <div class={[`layout-header__menu `]}> */}
|
||||
<LayoutMenu
|
||||
isHorizontal={true}
|
||||
class={`justify-${unref(getTopMenuAlign)}`}
|
||||
// class={`justify-${unref(getTopMenuAlign)}`}
|
||||
theme={unref(getHeaderTheme)}
|
||||
splitType={unref(getSplitType)}
|
||||
menuMode={unref(getMenuMode)}
|
||||
|
@ -21,7 +21,7 @@ export default defineComponent({
|
||||
|
||||
const injectValue = useLayoutContext();
|
||||
|
||||
const { getCalcContentWidth } = useMenuSetting();
|
||||
const { getCalcContentWidth, getSplit } = useMenuSetting();
|
||||
|
||||
const {
|
||||
getFixed,
|
||||
@ -56,7 +56,8 @@ export default defineComponent({
|
||||
(): CSSProperties => {
|
||||
const style: CSSProperties = {};
|
||||
if (unref(getFixed)) {
|
||||
style.width = unref(injectValue.isMobile) ? '100%' : unref(getCalcContentWidth);
|
||||
style.width =
|
||||
unref(injectValue.isMobile) || unref(getSplit) ? '100%' : unref(getCalcContentWidth);
|
||||
}
|
||||
if (unref(getShowFullHeaderRef)) {
|
||||
style.top = `${unref(fullHeaderHeightRef)}px`;
|
||||
|
@ -1,21 +1,21 @@
|
||||
import './index.less';
|
||||
|
||||
import { PropType, toRef } from 'vue';
|
||||
import type { Menu } from '/@/router/types';
|
||||
|
||||
import { computed, defineComponent, unref } from 'vue';
|
||||
import { BasicMenu } from '/@/components/Menu/index';
|
||||
import { BasicMenu } from '/@/components/Menu';
|
||||
import { AppLogo } from '/@/components/Application';
|
||||
|
||||
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import { useSplitMenu } from './useLayoutMenu';
|
||||
import { openWindow } from '/@/utils';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { isUrl } from '/@/utils/is';
|
||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LayoutMenu',
|
||||
@ -38,56 +38,46 @@ export default defineComponent({
|
||||
const go = useGo();
|
||||
|
||||
const {
|
||||
setMenuSetting,
|
||||
getMenuMode,
|
||||
getMenuType,
|
||||
getCollapsedShowTitle,
|
||||
getIsSidebarType,
|
||||
getMenuTheme,
|
||||
getCollapsed,
|
||||
getAccordion,
|
||||
getIsSidebarType,
|
||||
} = useMenuSetting();
|
||||
|
||||
const { getShowLogo } = useRootSetting();
|
||||
|
||||
const { flatMenusRef, menusRef } = useSplitMenu(toRef(props, 'splitType'));
|
||||
|
||||
const showLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
|
||||
const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
|
||||
|
||||
const getComputedMenuMode = computed(() => props.menuMode || unref(getMenuMode));
|
||||
|
||||
const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
|
||||
|
||||
const showLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
|
||||
const appendClass = computed(() => props.splitType === MenuSplitTyeEnum.TOP);
|
||||
|
||||
/**
|
||||
* click menu
|
||||
* @param menu
|
||||
*/
|
||||
function handleMenuClick(menu: Menu) {
|
||||
go(menu.path);
|
||||
function handleMenuClick(path: string) {
|
||||
go(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* before click menu
|
||||
* @param menu
|
||||
*/
|
||||
async function beforeMenuClickFn(menu: Menu) {
|
||||
const { meta: { externalLink } = {} } = menu;
|
||||
|
||||
if (externalLink) {
|
||||
openWindow(externalLink);
|
||||
return false;
|
||||
async function beforeMenuClickFn(path: string) {
|
||||
if (!isUrl(path)) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function handleClickSearchInput() {
|
||||
unref(getCollapsed) && setMenuSetting({ collapsed: false });
|
||||
openWindow(path);
|
||||
return false;
|
||||
}
|
||||
|
||||
function renderHeader() {
|
||||
if (!unref(showLogo)) return null;
|
||||
|
||||
return (
|
||||
<AppLogo
|
||||
showTitle={!unref(getCollapsed)}
|
||||
@ -100,20 +90,17 @@ export default defineComponent({
|
||||
return () => {
|
||||
return (
|
||||
<BasicMenu
|
||||
class="layout-menu"
|
||||
beforeClickFn={beforeMenuClickFn}
|
||||
isHorizontal={props.isHorizontal}
|
||||
appendClass={unref(appendClass)}
|
||||
type={unref(getMenuType)}
|
||||
mode={unref(getComputedMenuMode)}
|
||||
collapsedShowTitle={unref(getCollapsedShowTitle)}
|
||||
theme={unref(getComputedMenuTheme)}
|
||||
showLogo={unref(showLogo)}
|
||||
items={unref(menusRef)}
|
||||
flatItems={unref(flatMenusRef)}
|
||||
accordion={unref(getAccordion)}
|
||||
onMenuClick={handleMenuClick}
|
||||
onClickSearchInput={handleClickSearchInput}
|
||||
appendClass={unref(appendClass)}
|
||||
showLogo={unref(showLogo)}
|
||||
>
|
||||
{{
|
||||
header: () => renderHeader(),
|
||||
|
@ -8,24 +8,12 @@ import { MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
import { useThrottle } from '/@/hooks/core/useThrottle';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
|
||||
import {
|
||||
getChildrenMenus,
|
||||
getCurrentParentPath,
|
||||
getFlatChildrenMenus,
|
||||
getFlatMenus,
|
||||
getMenus,
|
||||
getShallowMenus,
|
||||
} from '/@/router/menus';
|
||||
import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus';
|
||||
import { permissionStore } from '/@/store/modules/permission';
|
||||
// import { useI18n } from '/@/hooks/web/useI18n';
|
||||
// import { cloneDeep } from 'lodash-es';
|
||||
|
||||
// const { t } = useI18n();
|
||||
export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
||||
// Menu array
|
||||
const menusRef = ref<Menu[]>([]);
|
||||
// flat menu array
|
||||
const flatMenusRef = ref<Menu[]>([]);
|
||||
|
||||
const { currentRoute } = useRouter();
|
||||
|
||||
@ -45,14 +33,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
||||
return unref(splitType) === MenuSplitTyeEnum.NONE || !unref(getSplit);
|
||||
});
|
||||
|
||||
// const getI18nFlatMenus = computed(() => {
|
||||
// return setI18nName(flatMenusRef.value, true, false);
|
||||
// });
|
||||
|
||||
// const getI18nMenus = computed(() => {
|
||||
// return setI18nName(menusRef.value, true, true);
|
||||
// });
|
||||
|
||||
watch(
|
||||
[() => unref(currentRoute).path, () => unref(splitType)],
|
||||
async ([path]: [string, MenuSplitTyeEnum]) => {
|
||||
@ -83,20 +63,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
||||
genMenus();
|
||||
});
|
||||
|
||||
// function setI18nName(list: Menu[], clone = false, deep = true) {
|
||||
// const menus = clone ? cloneDeep(list) : list;
|
||||
// const arr: Menu[] = [];
|
||||
// menus.forEach((item) => {
|
||||
// if (!item.name.includes('.')) return;
|
||||
// item.name = t(item.name);
|
||||
|
||||
// if (item.children && deep) {
|
||||
// setI18nName(item.children, false, deep);
|
||||
// }
|
||||
// });
|
||||
// return menus;
|
||||
// }
|
||||
|
||||
// Handle left menu split
|
||||
async function handleSplitLeftMenu(parentPath: string) {
|
||||
if (unref(splitLeft)) return;
|
||||
@ -105,14 +71,11 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
||||
const children = await getChildrenMenus(parentPath);
|
||||
if (!children) {
|
||||
setMenuSetting({ hidden: false });
|
||||
flatMenusRef.value = [];
|
||||
menusRef.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const flatChildren = await getFlatChildrenMenus(children);
|
||||
setMenuSetting({ hidden: true });
|
||||
flatMenusRef.value = flatChildren;
|
||||
menusRef.value = children;
|
||||
}
|
||||
|
||||
@ -120,7 +83,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
||||
async function genMenus() {
|
||||
// normal mode
|
||||
if (unref(normalType)) {
|
||||
flatMenusRef.value = await getFlatMenus();
|
||||
menusRef.value = await getMenus();
|
||||
return;
|
||||
}
|
||||
@ -129,11 +91,10 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
||||
if (unref(spiltTop)) {
|
||||
const shallowMenus = await getShallowMenus();
|
||||
|
||||
flatMenusRef.value = shallowMenus;
|
||||
menusRef.value = shallowMenus;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return { flatMenusRef, menusRef };
|
||||
return { menusRef };
|
||||
}
|
||||
|
@ -12,10 +12,25 @@
|
||||
|
||||
&.ant-layout-sider-dark {
|
||||
background: @sider-dark-bg-color;
|
||||
|
||||
.ant-layout-sider-trigger {
|
||||
color: darken(@white, 25%);
|
||||
background: @trigger-dark-bg-color;
|
||||
|
||||
&:hover {
|
||||
color: @white;
|
||||
background: @trigger-dark-hover-bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.ant-layout-sider-dark) {
|
||||
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
|
||||
|
||||
.ant-layout-sider-trigger {
|
||||
color: @text-color-base;
|
||||
border-top: 1px solid @border-color-light;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-sider-zero-width-trigger {
|
||||
@ -43,9 +58,9 @@
|
||||
box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-sider-trigger {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
& .ant-layout-sider-trigger {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ export default defineComponent({
|
||||
flex: `0 0 ${width}`,
|
||||
maxWidth: width,
|
||||
minWidth: width,
|
||||
transition: 'all 0.2s',
|
||||
transition: 'all 0.15s',
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -126,7 +126,7 @@ export default defineComponent({
|
||||
)}
|
||||
<Layout.Sider
|
||||
ref={sideRef}
|
||||
breakpoint="md"
|
||||
breakpoint="lg"
|
||||
collapsible
|
||||
class={unref(getSiderClass)}
|
||||
style={unref(getSiderStyle)}
|
||||
|
@ -79,3 +79,8 @@ export const isMobile = (): boolean => {
|
||||
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
|
||||
);
|
||||
};
|
||||
|
||||
export const isUrl = (path: string): boolean => {
|
||||
const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
|
||||
return reg.test(path);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user