|
|
|
@ -1,5 +1,5 @@ |
|
|
|
<template> |
|
|
|
<div :class="`${prefixCls}-dom`" /> |
|
|
|
<div :class="`${prefixCls}-dom`" :style="getDomStyle" /> |
|
|
|
|
|
|
|
<div |
|
|
|
v-click-outside="handleClickOutside" |
|
|
|
@ -27,7 +27,7 @@ |
|
|
|
v-bind="getItemEvents(item)" |
|
|
|
> |
|
|
|
<MenuTag :item="item" :showTitle="false" :isHorizontal="false" /> |
|
|
|
<g-icon |
|
|
|
<Icon |
|
|
|
:class="`${prefixCls}-module__icon`" |
|
|
|
:size="22" |
|
|
|
:icon="item.meta && item.meta.icon" |
|
|
|
@ -48,6 +48,14 @@ |
|
|
|
]" |
|
|
|
> |
|
|
|
<span class="text"> {{ title }}</span> |
|
|
|
<Icon |
|
|
|
:size="16" |
|
|
|
v-if="getMixSideFixed" |
|
|
|
icon="ri:pushpin-2-fill" |
|
|
|
class="pushpin" |
|
|
|
@click="handleFixedMenu" |
|
|
|
/> |
|
|
|
<Icon :size="16" v-else icon="ri:pushpin-2-line" class="pushpin" @click="handleFixedMenu" /> |
|
|
|
</div> |
|
|
|
<ScrollContainer :class="`${prefixCls}-menu-list__content`"> |
|
|
|
<BasicMenu |
|
|
|
@ -70,20 +78,23 @@ |
|
|
|
<script lang="ts"> |
|
|
|
import { defineComponent, onMounted, ref, computed, CSSProperties, unref } from 'vue'; |
|
|
|
import type { Menu } from '/@/router/types'; |
|
|
|
import type { RouteLocationNormalized } from 'vue-router'; |
|
|
|
import { RouteLocationNormalized } from 'vue-router'; |
|
|
|
import { useDesign } from '/@/hooks/web/useDesign'; |
|
|
|
import { getShallowMenus, getChildrenMenus, getCurrentParentPath } from '/@/router/menus'; |
|
|
|
import { useI18n } from '/@/hooks/web/useI18n'; |
|
|
|
import { ScrollContainer } from '/@/components/Container'; |
|
|
|
import Icon from '/@/components/Icon'; |
|
|
|
import { AppLogo } from '/@/components/Application'; |
|
|
|
import { useGo } from '/@/hooks/web/usePage'; |
|
|
|
import { BasicMenu, MenuTag } from '/@/components/Menu'; |
|
|
|
import { listenerLastChangeTab } from '/@/logics/mitt/tabChange'; |
|
|
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
|
|
|
import { useDragLine } from './useLayoutSider'; |
|
|
|
import { useGlobSetting } from '/@/hooks/setting'; |
|
|
|
|
|
|
|
import { SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; |
|
|
|
|
|
|
|
import clickOutside from '/@/directives/clickOutside'; |
|
|
|
import { useGlobSetting } from '/@/hooks/setting'; |
|
|
|
|
|
|
|
export default defineComponent({ |
|
|
|
name: 'LayoutMixSider', |
|
|
|
@ -92,6 +103,7 @@ |
|
|
|
AppLogo, |
|
|
|
BasicMenu, |
|
|
|
MenuTag, |
|
|
|
Icon, |
|
|
|
}, |
|
|
|
directives: { |
|
|
|
clickOutside, |
|
|
|
@ -101,6 +113,7 @@ |
|
|
|
const activePath = ref(''); |
|
|
|
const chilrenMenus = ref<Menu[]>([]); |
|
|
|
const openMenu = ref(false); |
|
|
|
const isInit = ref(false); |
|
|
|
const dragBarRef = ref<ElRef>(null); |
|
|
|
const sideRef = ref<ElRef>(null); |
|
|
|
const currentRoute = ref<Nullable<RouteLocationNormalized>>(null); |
|
|
|
@ -114,7 +127,12 @@ |
|
|
|
getCloseMixSidebarOnChange, |
|
|
|
getMenuTheme, |
|
|
|
getMixSideTrigger, |
|
|
|
getRealWidth, |
|
|
|
getMixSideFixed, |
|
|
|
mixSideHasChildren, |
|
|
|
setMenuSetting, |
|
|
|
} = useMenuSetting(); |
|
|
|
|
|
|
|
const { title } = useGlobSetting(); |
|
|
|
|
|
|
|
useDragLine(sideRef, dragBarRef, true); |
|
|
|
@ -127,14 +145,41 @@ |
|
|
|
} |
|
|
|
); |
|
|
|
|
|
|
|
const getIsFixed = computed(() => { |
|
|
|
mixSideHasChildren.value = unref(chilrenMenus).length > 0; |
|
|
|
const isFixed = unref(getMixSideFixed) && unref(mixSideHasChildren); |
|
|
|
if (isFixed) { |
|
|
|
openMenu.value = true; |
|
|
|
} |
|
|
|
return isFixed; |
|
|
|
}); |
|
|
|
|
|
|
|
const getDomStyle = computed( |
|
|
|
(): CSSProperties => { |
|
|
|
const fixedWidth = unref(getIsFixed) ? unref(getRealWidth) : 0; |
|
|
|
const width = `${SIDE_BAR_SHOW_TIT_MINI_WIDTH + fixedWidth}px`; |
|
|
|
return { |
|
|
|
width, |
|
|
|
maxWidth: width, |
|
|
|
minWidth: width, |
|
|
|
flex: `0 0 ${width}`, |
|
|
|
}; |
|
|
|
} |
|
|
|
); |
|
|
|
|
|
|
|
const getMenuEvents = computed(() => { |
|
|
|
return unref(getMixSideTrigger) === 'hover' |
|
|
|
? { |
|
|
|
onMouseleave: () => { |
|
|
|
openMenu.value = false; |
|
|
|
}, |
|
|
|
} |
|
|
|
: {}; |
|
|
|
// return unref(getMixSideTrigger) === 'hover' |
|
|
|
// ? { |
|
|
|
// onMouseleave: () => { |
|
|
|
// closeMenu(); |
|
|
|
// }, |
|
|
|
// } |
|
|
|
// : {}; |
|
|
|
return { |
|
|
|
onMouseleave: () => { |
|
|
|
closeMenu(); |
|
|
|
}, |
|
|
|
}; |
|
|
|
}); |
|
|
|
|
|
|
|
const getShowDragBar = computed(() => unref(getCanDrag)); |
|
|
|
@ -145,9 +190,9 @@ |
|
|
|
|
|
|
|
listenerLastChangeTab((route) => { |
|
|
|
currentRoute.value = route; |
|
|
|
setActive(); |
|
|
|
setActive(true); |
|
|
|
if (unref(getCloseMixSidebarOnChange)) { |
|
|
|
openMenu.value = false; |
|
|
|
closeMenu(); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
@ -156,7 +201,11 @@ |
|
|
|
|
|
|
|
if (unref(activePath) === path) { |
|
|
|
if (!hover) { |
|
|
|
openMenu.value = !unref(openMenu); |
|
|
|
if (!unref(openMenu)) { |
|
|
|
openMenu.value = true; |
|
|
|
} else { |
|
|
|
closeMenu(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!unref(openMenu)) { |
|
|
|
setActive(); |
|
|
|
@ -169,18 +218,32 @@ |
|
|
|
if (!children || children.length === 0) { |
|
|
|
go(path); |
|
|
|
chilrenMenus.value = []; |
|
|
|
openMenu.value = false; |
|
|
|
closeMenu(); |
|
|
|
return; |
|
|
|
} |
|
|
|
chilrenMenus.value = children; |
|
|
|
} |
|
|
|
|
|
|
|
async function setActive() { |
|
|
|
async function setActive(setChildren = false) { |
|
|
|
const path = currentRoute.value?.path; |
|
|
|
if (!path) return; |
|
|
|
const parentPath = await getCurrentParentPath(path); |
|
|
|
activePath.value = parentPath; |
|
|
|
// hanldeModuleClick(parentPath); |
|
|
|
if (unref(getMixSideFixed)) { |
|
|
|
const activeMenu = unref(menuModules).find((item) => item.path === unref(activePath)); |
|
|
|
const p = activeMenu?.path; |
|
|
|
if (p) { |
|
|
|
const children = await getChildrenMenus(p); |
|
|
|
if (setChildren) { |
|
|
|
chilrenMenus.value = children; |
|
|
|
openMenu.value = children.length > 0; |
|
|
|
} |
|
|
|
if (children.length === 0) { |
|
|
|
chilrenMenus.value = []; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function handleMenuClick(path: string) { |
|
|
|
@ -188,7 +251,7 @@ |
|
|
|
} |
|
|
|
|
|
|
|
function handleClickOutside() { |
|
|
|
openMenu.value = false; |
|
|
|
closeMenu(); |
|
|
|
setActive(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -203,6 +266,18 @@ |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
function handleFixedMenu() { |
|
|
|
setMenuSetting({ |
|
|
|
mixSideFixed: !unref(getIsFixed), |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
function closeMenu() { |
|
|
|
if (!unref(getIsFixed)) { |
|
|
|
openMenu.value = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
t, |
|
|
|
prefixCls, |
|
|
|
@ -221,6 +296,9 @@ |
|
|
|
getMenuTheme, |
|
|
|
getItemEvents, |
|
|
|
getMenuEvents, |
|
|
|
getDomStyle, |
|
|
|
handleFixedMenu, |
|
|
|
getMixSideFixed, |
|
|
|
}; |
|
|
|
}, |
|
|
|
}); |
|
|
|
@ -241,7 +319,7 @@ |
|
|
|
min-width: @width; |
|
|
|
overflow: hidden; |
|
|
|
background: @sider-dark-bg-color; |
|
|
|
transition: all 0.2s ease 0s; |
|
|
|
transition: all 0.3s ease 0s; |
|
|
|
flex: 0 0 @width; |
|
|
|
.@{tag-prefix-cls} { |
|
|
|
position: absolute; |
|
|
|
@ -293,6 +371,17 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
.@{prefix-cls}-menu-list { |
|
|
|
&__title { |
|
|
|
.pushpin { |
|
|
|
color: rgba(0, 0, 0, 0.35); |
|
|
|
|
|
|
|
&:hover { |
|
|
|
color: rgba(0, 0, 0, 0.85); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@border-color: @sider-dark-lighten-1-bg-color; |
|
|
|
|
|
|
|
@ -388,20 +477,30 @@ |
|
|
|
&__title { |
|
|
|
display: flex; |
|
|
|
height: @header-height; |
|
|
|
margin-left: -6px; |
|
|
|
// margin-left: -6px; |
|
|
|
font-size: 18px; |
|
|
|
color: @primary-color; |
|
|
|
border-bottom: 1px solid rgb(238, 238, 238); |
|
|
|
opacity: 0; |
|
|
|
transition: unset; |
|
|
|
// justify-content: center; |
|
|
|
align-items: center; |
|
|
|
justify-content: start; |
|
|
|
justify-content: space-between; |
|
|
|
|
|
|
|
&.show { |
|
|
|
min-width: 130px; |
|
|
|
opacity: 1; |
|
|
|
transition: all 0.5s ease; |
|
|
|
} |
|
|
|
|
|
|
|
.pushpin { |
|
|
|
margin-right: 6px; |
|
|
|
color: rgba(255, 255, 255, 0.65); |
|
|
|
cursor: pointer; |
|
|
|
|
|
|
|
&:hover { |
|
|
|
color: #fff; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
&__content { |
|
|
|
|