79 changed files with 1381 additions and 1184 deletions
@ -1,7 +1,8 @@ |
|||||
import AppLocalPicker from './src/AppLocalPicker.vue'; |
import AppLocalPicker from './src/AppLocalPicker.vue'; |
||||
import AppFooterToolbar from './src/AppFooterToolbar.vue'; |
import AppPageFooter from './src/AppPageFooter.vue'; |
||||
|
import AppLogo from './src/AppLogo.vue'; |
||||
import { withInstall } from '../util'; |
import { withInstall } from '../util'; |
||||
|
|
||||
export { AppLocalPicker, AppFooterToolbar }; |
export { AppLocalPicker, AppPageFooter, AppLogo }; |
||||
|
|
||||
export default withInstall(AppLocalPicker, AppFooterToolbar); |
export default withInstall(AppLocalPicker, AppPageFooter, AppLogo); |
||||
|
|||||
@ -1,60 +0,0 @@ |
|||||
<template> |
|
||||
<div class="app-footer" :style="{ width: getWidth }"> |
|
||||
<div class="app-footer__left"> |
|
||||
<slot name="left" /> |
|
||||
</div> |
|
||||
<div class="app-footer__right"> |
|
||||
<slot name="right" /> |
|
||||
</div> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script lang="ts"> |
|
||||
import { defineComponent, computed, unref } from 'vue'; |
|
||||
|
|
||||
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; |
|
||||
|
|
||||
import { appStore } from '/@/store/modules/app'; |
|
||||
import { menuStore } from '/@/store/modules/menu'; |
|
||||
|
|
||||
export default defineComponent({ |
|
||||
name: 'AppFooterToolbar', |
|
||||
setup() { |
|
||||
const getMiniWidth = computed(() => { |
|
||||
const { |
|
||||
menuSetting: { collapsedShowTitle }, |
|
||||
} = appStore.getProjectConfig; |
|
||||
return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH; |
|
||||
}); |
|
||||
|
|
||||
const getWidth = computed(() => { |
|
||||
const { getCollapsedState, getMenuWidthState } = menuStore; |
|
||||
const width = getCollapsedState ? unref(getMiniWidth) : getMenuWidthState; |
|
||||
return `calc(100% - ${width}px)`; |
|
||||
}); |
|
||||
|
|
||||
return { getWidth }; |
|
||||
}, |
|
||||
}); |
|
||||
</script> |
|
||||
<style lang="less" scoped> |
|
||||
.app-footer { |
|
||||
position: fixed; |
|
||||
right: 0; |
|
||||
bottom: 0; |
|
||||
z-index: 99; |
|
||||
display: flex; |
|
||||
width: 100%; |
|
||||
align-items: center; |
|
||||
padding: 0 24px; |
|
||||
line-height: 44px; |
|
||||
background: #fff; |
|
||||
border-top: 1px solid #f0f0f0; |
|
||||
box-shadow: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05), |
|
||||
0 -12px 48px 16px rgba(0, 0, 0, 0.03); |
|
||||
transition: width 0.3s; |
|
||||
|
|
||||
&__left { |
|
||||
flex: 1 1; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -0,0 +1,72 @@ |
|||||
|
<template> |
||||
|
<div class="app-logo anticon" :class="theme" @click="handleGoHome"> |
||||
|
<img src="/@/assets/images/logo.png" /> |
||||
|
<div class="app-logo__title ml-2 ellipsis">{{ globSetting.title }}</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts"> |
||||
|
import type { PropType } from 'vue'; |
||||
|
import { defineComponent } from 'vue'; |
||||
|
|
||||
|
import { useGlobSetting } from '/@/hooks/setting'; |
||||
|
import { useGo } from '/@/hooks/web/usePage'; |
||||
|
|
||||
|
import { PageEnum } from '/@/enums/pageEnum'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'AppLogo', |
||||
|
props: { |
||||
|
/** |
||||
|
* The theme of the current parent component |
||||
|
*/ |
||||
|
theme: { |
||||
|
type: String as PropType<string>, |
||||
|
}, |
||||
|
}, |
||||
|
setup() { |
||||
|
const globSetting = useGlobSetting(); |
||||
|
const go = useGo(); |
||||
|
|
||||
|
function handleGoHome(): void { |
||||
|
go(PageEnum.BASE_HOME); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
handleGoHome, |
||||
|
globSetting, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
@import (reference) '../../../design/index.less'; |
||||
|
|
||||
|
.app-logo { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding-left: 16px; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
&.light { |
||||
|
border-bottom: 1px solid @border-color-base; |
||||
|
} |
||||
|
|
||||
|
&.light &__title { |
||||
|
color: @primary-color; |
||||
|
} |
||||
|
|
||||
|
&.dark &__title { |
||||
|
color: @white; |
||||
|
} |
||||
|
|
||||
|
&__title { |
||||
|
font-size: 18px; |
||||
|
font-weight: 700; |
||||
|
opacity: 0; |
||||
|
transition: all 0.5s; |
||||
|
.respond-to(medium,{ |
||||
|
opacity: 1; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,46 @@ |
|||||
|
<template> |
||||
|
<div class="app-footer" :style="{ width: getCalcContentWidth }"> |
||||
|
<div class="app-footer__left"> |
||||
|
<slot name="left" /> |
||||
|
</div> |
||||
|
<div class="app-footer__right"> |
||||
|
<slot name="right" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts"> |
||||
|
import { defineComponent } from 'vue'; |
||||
|
|
||||
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'AppFooterToolbar', |
||||
|
setup() { |
||||
|
const { getCalcContentWidth } = useMenuSetting(); |
||||
|
|
||||
|
return { getCalcContentWidth }; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
.app-footer { |
||||
|
position: fixed; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
z-index: 99; |
||||
|
display: flex; |
||||
|
width: 100%; |
||||
|
align-items: center; |
||||
|
padding: 0 24px; |
||||
|
line-height: 44px; |
||||
|
background: #fff; |
||||
|
border-top: 1px solid #f0f0f0; |
||||
|
box-shadow: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05), |
||||
|
0 -12px 48px 16px rgba(0, 0, 0, 0.03); |
||||
|
transition: width 0.4s; |
||||
|
|
||||
|
&__left { |
||||
|
flex: 1 1; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -1 +1,5 @@ |
|||||
export { default as BasicMenu } from './src/BasicMenu'; |
import BasicMenu from './src/BasicMenu'; |
||||
|
import { withInstall } from '../util'; |
||||
|
|
||||
|
export default withInstall(BasicMenu); |
||||
|
export { BasicMenu }; |
||||
|
|||||
@ -1,5 +1,5 @@ |
|||||
import type { Menu as MenuType } from '/@/router/types'; |
import type { Menu as MenuType } from '/@/router/types'; |
||||
import type { MenuState } from './types'; |
import type { MenuState } from '../types'; |
||||
import type { Ref } from 'vue'; |
import type { Ref } from 'vue'; |
||||
|
|
||||
import { isString } from '/@/utils/is'; |
import { isString } from '/@/utils/is'; |
||||
@ -0,0 +1,3 @@ |
|||||
|
import { defineComponent } from 'vue'; |
||||
|
|
||||
|
export type Component = ReturnType<typeof defineComponent>; |
||||
@ -0,0 +1,20 @@ |
|||||
|
import { customRef } from 'vue'; |
||||
|
|
||||
|
export function useDebouncedRef<T = any>(value: T, delay = 100) { |
||||
|
let timeout: TimeoutHandle; |
||||
|
return customRef((track, trigger) => { |
||||
|
return { |
||||
|
get() { |
||||
|
track(); |
||||
|
return value; |
||||
|
}, |
||||
|
set(newValue: T) { |
||||
|
clearTimeout(timeout); |
||||
|
timeout = setTimeout(() => { |
||||
|
value = newValue; |
||||
|
trigger(); |
||||
|
}, delay); |
||||
|
}, |
||||
|
}; |
||||
|
}); |
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
import type { HeaderSetting } from '/@/types/config'; |
||||
|
|
||||
|
import { computed, unref } from 'vue'; |
||||
|
|
||||
|
import { appStore } from '/@/store/modules/app'; |
||||
|
|
||||
|
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; |
||||
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
||||
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
||||
|
|
||||
|
import { MenuModeEnum } from '/@/enums/menuEnum'; |
||||
|
|
||||
|
export function useHeaderSetting() { |
||||
|
const { getShow: getShowMultipleTab } = useMultipleTabSetting(); |
||||
|
const { getMode, getSplit, getShowHeaderTrigger, getIsSidebarType } = useMenuSetting(); |
||||
|
const { getShowBreadCrumb, getShowLogo } = useRootSetting(); |
||||
|
|
||||
|
// Get header configuration
|
||||
|
const getHeaderSetting = computed(() => appStore.getProjectConfig.headerSetting); |
||||
|
|
||||
|
const getShowDoc = computed(() => unref(getHeaderSetting).showDoc); |
||||
|
|
||||
|
const getTheme = computed(() => unref(getHeaderSetting).theme); |
||||
|
|
||||
|
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 getShowBread = computed(() => { |
||||
|
return ( |
||||
|
unref(getMode) !== 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, |
||||
|
|
||||
|
getHeaderSetting, |
||||
|
|
||||
|
getShowDoc, |
||||
|
getTheme, |
||||
|
getShowRedo, |
||||
|
getUseLockPage, |
||||
|
getShowFullScreen, |
||||
|
getShowNotice, |
||||
|
getShowBread, |
||||
|
getShowContent, |
||||
|
getShowHeaderLogo, |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,120 @@ |
|||||
|
import type { MenuSetting } from '/@/types/config'; |
||||
|
|
||||
|
import { computed, unref } from 'vue'; |
||||
|
|
||||
|
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'; |
||||
|
|
||||
|
export function useMenuSetting() { |
||||
|
// Get menu configuration
|
||||
|
const getMenuSetting = computed(() => appStore.getProjectConfig.menuSetting); |
||||
|
|
||||
|
const getMiniWidth = computed(() => unref(getMenuSetting).menuWidth); |
||||
|
|
||||
|
const getCollapsed = computed(() => unref(getMenuSetting).collapsed); |
||||
|
|
||||
|
const getType = computed(() => unref(getMenuSetting).type); |
||||
|
|
||||
|
const getMode = computed(() => unref(getMenuSetting).mode); |
||||
|
|
||||
|
const getShow = computed(() => unref(getMenuSetting).show); |
||||
|
|
||||
|
const getMenuWidth = computed(() => unref(getMenuSetting).menuWidth); |
||||
|
|
||||
|
const getTrigger = computed(() => unref(getMenuSetting).trigger); |
||||
|
|
||||
|
const getTheme = computed(() => unref(getMenuSetting).theme); |
||||
|
|
||||
|
const getSplit = computed(() => unref(getMenuSetting).split); |
||||
|
|
||||
|
const getHasDrag = computed(() => unref(getMenuSetting).hasDrag); |
||||
|
|
||||
|
const getAccordion = computed(() => unref(getMenuSetting).accordion); |
||||
|
|
||||
|
const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle); |
||||
|
|
||||
|
const getCollapsedShowSearch = computed(() => unref(getMenuSetting).collapsedShowSearch); |
||||
|
|
||||
|
const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign); |
||||
|
|
||||
|
const getIsSidebarType = computed(() => unref(getType) === MenuTypeEnum.SIDEBAR); |
||||
|
|
||||
|
const getShowTopMenu = computed(() => { |
||||
|
return unref(getMode) === MenuModeEnum.HORIZONTAL || unref(getSplit); |
||||
|
}); |
||||
|
|
||||
|
const getShowHeaderTrigger = computed(() => { |
||||
|
if ( |
||||
|
unref(getType) === MenuTypeEnum.TOP_MENU || |
||||
|
!unref(getShow) || |
||||
|
!unref(getMenuSetting).hidden |
||||
|
) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return unref(getTrigger) === TriggerEnum.HEADER; |
||||
|
}); |
||||
|
|
||||
|
const getShowSearch = computed(() => { |
||||
|
return ( |
||||
|
unref(getMenuSetting).showSearch && |
||||
|
!(unref(getType) === MenuTypeEnum.MIX && unref(getMode) === MenuModeEnum.HORIZONTAL) |
||||
|
); |
||||
|
}); |
||||
|
|
||||
|
const getIsHorizontal = computed(() => { |
||||
|
return unref(getMode) === MenuModeEnum.HORIZONTAL; |
||||
|
}); |
||||
|
|
||||
|
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(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMiniWidth); |
||||
|
return `calc(100% - ${width}px)`; |
||||
|
}); |
||||
|
|
||||
|
// Set menu configuration
|
||||
|
function setMenuSetting(menuSetting: Partial<MenuSetting>): void { |
||||
|
appStore.commitProjectConfigState({ menuSetting }); |
||||
|
} |
||||
|
|
||||
|
function toggleCollapsed() { |
||||
|
setMenuSetting({ |
||||
|
collapsed: !unref(getCollapsed), |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
setMenuSetting, |
||||
|
|
||||
|
toggleCollapsed, |
||||
|
|
||||
|
getMenuSetting, |
||||
|
getMiniWidth, |
||||
|
getType, |
||||
|
getMode, |
||||
|
getShow, |
||||
|
getCollapsed, |
||||
|
getMiniWidthNumber, |
||||
|
getCalcContentWidth, |
||||
|
getMenuWidth, |
||||
|
getTrigger, |
||||
|
getSplit, |
||||
|
getTheme, |
||||
|
getHasDrag, |
||||
|
getIsHorizontal, |
||||
|
getShowSearch, |
||||
|
getCollapsedShowTitle, |
||||
|
getCollapsedShowSearch, |
||||
|
getIsSidebarType, |
||||
|
getAccordion, |
||||
|
getShowTopMenu, |
||||
|
getShowHeaderTrigger, |
||||
|
getTopMenuAlign, |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
import type { MultiTabsSetting } from '/@/types/config'; |
||||
|
|
||||
|
import { computed, unref } from 'vue'; |
||||
|
|
||||
|
import { appStore } from '/@/store/modules/app'; |
||||
|
|
||||
|
export function useMultipleTabSetting() { |
||||
|
const getMultipleTabSetting = computed(() => appStore.getProjectConfig.multiTabsSetting); |
||||
|
|
||||
|
const getMax = computed(() => unref(getMultipleTabSetting).max); |
||||
|
|
||||
|
const getShow = computed(() => unref(getMultipleTabSetting).show); |
||||
|
|
||||
|
function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) { |
||||
|
appStore.commitProjectConfigState({ multiTabsSetting }); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
setMultipleTabSetting, |
||||
|
|
||||
|
getMultipleTabSetting, |
||||
|
getMax, |
||||
|
getShow, |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
import type { ProjectConfig } from '/@/types/config'; |
||||
|
|
||||
|
import { computed, unref } from 'vue'; |
||||
|
|
||||
|
import { appStore } from '/@/store/modules/app'; |
||||
|
|
||||
|
type RootSetting = Omit< |
||||
|
ProjectConfig, |
||||
|
'locale' | 'headerSetting' | 'menuSetting' | 'multiTabsSetting' |
||||
|
>; |
||||
|
export function useRootSetting() { |
||||
|
const getRootSetting = computed((): RootSetting => appStore.getProjectConfig); |
||||
|
|
||||
|
const getOpenPageLoading = computed(() => unref(getRootSetting).openPageLoading); |
||||
|
|
||||
|
const getOpenRouterTransition = computed(() => unref(getRootSetting).openRouterTransition); |
||||
|
|
||||
|
const getOpenKeepAlive = computed(() => unref(getRootSetting).openKeepAlive); |
||||
|
|
||||
|
const getRouterTransition = computed(() => unref(getRootSetting).routerTransition); |
||||
|
|
||||
|
const getCanEmbedIFramePage = computed(() => unref(getRootSetting).canEmbedIFramePage); |
||||
|
|
||||
|
const getPermissionMode = computed(() => unref(getRootSetting).permissionMode); |
||||
|
|
||||
|
const getShowLogo = computed(() => unref(getRootSetting).showLogo); |
||||
|
|
||||
|
const getUseErrorHandle = computed(() => unref(getRootSetting).useErrorHandle); |
||||
|
|
||||
|
const getShowBreadCrumb = computed(() => unref(getRootSetting).showBreadCrumb); |
||||
|
|
||||
|
const getShowBreadCrumbIcon = computed(() => unref(getRootSetting).showBreadCrumbIcon); |
||||
|
|
||||
|
function setRootSetting(setting: RootSetting) { |
||||
|
appStore.commitProjectConfigState(setting); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
setRootSetting, |
||||
|
|
||||
|
getRootSetting, |
||||
|
getOpenPageLoading, |
||||
|
getOpenRouterTransition, |
||||
|
getOpenKeepAlive, |
||||
|
getRouterTransition, |
||||
|
getCanEmbedIFramePage, |
||||
|
getPermissionMode, |
||||
|
getShowLogo, |
||||
|
getUseErrorHandle, |
||||
|
getShowBreadCrumb, |
||||
|
getShowBreadCrumbIcon, |
||||
|
}; |
||||
|
} |
||||
@ -1,20 +0,0 @@ |
|||||
import { computed } from 'vue'; |
|
||||
import { appStore } from '/@/store/modules/app'; |
|
||||
|
|
||||
export function useSideBar() { |
|
||||
const currentCollapsedRef = computed(() => { |
|
||||
return appStore.getProjectConfig.menuSetting.collapsed; |
|
||||
}); |
|
||||
const changeCollapsed = (collapsed: boolean) => { |
|
||||
appStore.commitProjectConfigState({ |
|
||||
menuSetting: { |
|
||||
collapsed: collapsed, |
|
||||
}, |
|
||||
}); |
|
||||
}; |
|
||||
return { |
|
||||
openSider: changeCollapsed(false), |
|
||||
closeSider: changeCollapsed(true), |
|
||||
currentCollapsedRef, |
|
||||
}; |
|
||||
} |
|
||||
@ -1,214 +0,0 @@ |
|||||
import { computed, defineComponent, nextTick, onMounted, ref, unref } from 'vue'; |
|
||||
|
|
||||
import { Layout } from 'ant-design-vue'; |
|
||||
import LayoutTrigger from './LayoutTrigger'; |
|
||||
import LayoutMenu from '/@/layouts/default/menu/LayoutMenu'; |
|
||||
|
|
||||
import { menuStore } from '/@/store/modules/menu'; |
|
||||
import { appStore } from '/@/store/modules/app'; |
|
||||
|
|
||||
import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum'; |
|
||||
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; |
|
||||
|
|
||||
import { useDebounce } from '/@/hooks/core/useDebounce'; |
|
||||
|
|
||||
export default defineComponent({ |
|
||||
name: 'DefaultLayoutSideBar', |
|
||||
setup() { |
|
||||
const initRef = ref(false); |
|
||||
const brokenRef = ref(false); |
|
||||
const collapseRef = ref(true); |
|
||||
const dragBarRef = ref<Nullable<HTMLDivElement>>(null); |
|
||||
const sideRef = ref<any>(null); |
|
||||
|
|
||||
const getProjectConfigRef = computed(() => { |
|
||||
return appStore.getProjectConfig; |
|
||||
}); |
|
||||
|
|
||||
const getMiniWidth = computed(() => { |
|
||||
const { |
|
||||
menuSetting: { collapsedShowTitle }, |
|
||||
} = unref(getProjectConfigRef); |
|
||||
return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH; |
|
||||
}); |
|
||||
|
|
||||
function onCollapseChange(val: boolean) { |
|
||||
if (initRef.value) { |
|
||||
collapseRef.value = val; |
|
||||
menuStore.commitCollapsedState(val); |
|
||||
} else { |
|
||||
const collapsed = appStore.getProjectConfig.menuSetting.collapsed; |
|
||||
!collapsed && menuStore.commitCollapsedState(val); |
|
||||
} |
|
||||
initRef.value = true; |
|
||||
} |
|
||||
|
|
||||
// Menu area drag and drop-mouse movement
|
|
||||
function handleMouseMove(ele: any, wrap: any, clientX: number) { |
|
||||
document.onmousemove = function (innerE) { |
|
||||
let iT = ele.left + ((innerE || event).clientX - clientX); |
|
||||
innerE = innerE || window.event; |
|
||||
// let tarnameb = innerE.target || innerE.srcElement;
|
|
||||
const maxT = 600; |
|
||||
const minT = unref(getMiniWidth); |
|
||||
iT < 0 && (iT = 0); |
|
||||
iT > maxT && (iT = maxT); |
|
||||
iT < minT && (iT = minT); |
|
||||
ele.style.left = wrap.style.width = iT + 'px'; |
|
||||
return false; |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
// 菜单区域拖拽 - 鼠标松开
|
|
||||
function removeMouseup(ele: any) { |
|
||||
const wrap = unref(sideRef).$el; |
|
||||
document.onmouseup = function () { |
|
||||
document.onmousemove = null; |
|
||||
document.onmouseup = null; |
|
||||
const width = parseInt(wrap.style.width); |
|
||||
menuStore.commitDragStartState(false); |
|
||||
if (!menuStore.getCollapsedState) { |
|
||||
if (width > unref(getMiniWidth) + 20) { |
|
||||
setMenuWidth(width); |
|
||||
} else { |
|
||||
menuStore.commitCollapsedState(true); |
|
||||
} |
|
||||
} else { |
|
||||
if (width > unref(getMiniWidth)) { |
|
||||
setMenuWidth(width); |
|
||||
menuStore.commitCollapsedState(false); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
ele.releaseCapture && ele.releaseCapture(); |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
function setMenuWidth(width: number) { |
|
||||
appStore.commitProjectConfigState({ |
|
||||
menuSetting: { |
|
||||
menuWidth: width, |
|
||||
}, |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
function changeWrapWidth() { |
|
||||
const ele = unref(dragBarRef) as any; |
|
||||
const side = unref(sideRef); |
|
||||
|
|
||||
const wrap = (side || {}).$el; |
|
||||
ele && |
|
||||
(ele.onmousedown = (e: any) => { |
|
||||
menuStore.commitDragStartState(true); |
|
||||
wrap.style.transition = 'unset'; |
|
||||
const clientX = (e || event).clientX; |
|
||||
ele.left = ele.offsetLeft; |
|
||||
handleMouseMove(ele, wrap, clientX); |
|
||||
removeMouseup(ele); |
|
||||
ele.setCapture && ele.setCapture(); |
|
||||
return false; |
|
||||
}); |
|
||||
} |
|
||||
function handleBreakpoint(broken: boolean) { |
|
||||
brokenRef.value = broken; |
|
||||
} |
|
||||
|
|
||||
const getDragBarStyle = computed(() => { |
|
||||
if (menuStore.getCollapsedState) { |
|
||||
return { left: `${unref(getMiniWidth)}px` }; |
|
||||
} |
|
||||
return {}; |
|
||||
}); |
|
||||
|
|
||||
const getCollapsedWidth = computed(() => { |
|
||||
return unref(brokenRef) ? 0 : unref(getMiniWidth); |
|
||||
}); |
|
||||
|
|
||||
const showTrigger = computed(() => { |
|
||||
const { |
|
||||
menuSetting: { trigger }, |
|
||||
} = unref(getProjectConfigRef); |
|
||||
return trigger !== TriggerEnum.NONE && trigger === TriggerEnum.FOOTER; |
|
||||
}); |
|
||||
|
|
||||
onMounted(() => { |
|
||||
nextTick(() => { |
|
||||
const [exec] = useDebounce(changeWrapWidth, 20); |
|
||||
exec(); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
function handleSiderClick(e: ChangeEvent) { |
|
||||
if (!e || !e.target || e.target.className !== 'basic-menu__content') return; |
|
||||
|
|
||||
const { collapsed, show } = appStore.getProjectConfig.menuSetting; |
|
||||
if (!collapsed || !show) return; |
|
||||
appStore.commitProjectConfigState({ |
|
||||
menuSetting: { |
|
||||
collapsed: false, |
|
||||
}, |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
function renderDragLine() { |
|
||||
const { menuSetting: { hasDrag = true } = {} } = unref(getProjectConfigRef); |
|
||||
return ( |
|
||||
<div |
|
||||
class={[`layout-sidebar__dargbar`, !hasDrag ? 'hide' : '']} |
|
||||
style={unref(getDragBarStyle)} |
|
||||
ref={dragBarRef} |
|
||||
/> |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
return () => { |
|
||||
const { |
|
||||
menuSetting: { theme, split: splitMenu }, |
|
||||
} = unref(getProjectConfigRef); |
|
||||
const { getCollapsedState, getMenuWidthState } = menuStore; |
|
||||
|
|
||||
const triggerDom = unref(showTrigger) |
|
||||
? { |
|
||||
trigger: () => <LayoutTrigger />, |
|
||||
} |
|
||||
: {}; |
|
||||
|
|
||||
const triggerAttr = unref(showTrigger) |
|
||||
? {} |
|
||||
: { |
|
||||
trigger: null, |
|
||||
}; |
|
||||
|
|
||||
return ( |
|
||||
<Layout.Sider |
|
||||
onClick={handleSiderClick} |
|
||||
onCollapse={onCollapseChange} |
|
||||
breakpoint="md" |
|
||||
width={getMenuWidthState} |
|
||||
collapsed={getCollapsedState} |
|
||||
collapsible |
|
||||
collapsedWidth={unref(getCollapsedWidth)} |
|
||||
theme={theme} |
|
||||
class="layout-sidebar" |
|
||||
ref={sideRef} |
|
||||
onBreakpoint={handleBreakpoint} |
|
||||
{...triggerAttr} |
|
||||
> |
|
||||
{{ |
|
||||
...triggerDom, |
|
||||
default: () => ( |
|
||||
<> |
|
||||
<LayoutMenu |
|
||||
theme={theme} |
|
||||
menuMode={splitMenu ? MenuModeEnum.INLINE : null} |
|
||||
splitType={splitMenu ? MenuSplitTyeEnum.LEFT : MenuSplitTyeEnum.NONE} |
|
||||
/> |
|
||||
{renderDragLine()} |
|
||||
</> |
|
||||
), |
|
||||
}} |
|
||||
</Layout.Sider> |
|
||||
); |
|
||||
}; |
|
||||
}, |
|
||||
}); |
|
||||
@ -0,0 +1,113 @@ |
|||||
|
import type { Menu } from '/@/router/types'; |
||||
|
import type { Ref } from 'vue'; |
||||
|
|
||||
|
import { watch, unref, ref, computed } from 'vue'; |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
|
||||
|
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 { permissionStore } from '/@/store/modules/permission'; |
||||
|
|
||||
|
export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { |
||||
|
// Menu array
|
||||
|
const menusRef = ref<Menu[]>([]); |
||||
|
// flat menu array
|
||||
|
const flatMenusRef = ref<Menu[]>([]); |
||||
|
|
||||
|
const { currentRoute } = useRouter(); |
||||
|
|
||||
|
const { setMenuSetting, getIsHorizontal, getSplit } = useMenuSetting(); |
||||
|
|
||||
|
const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50); |
||||
|
|
||||
|
const splitNotLeft = computed( |
||||
|
() => unref(splitType) !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontal) |
||||
|
); |
||||
|
|
||||
|
const splitLeft = computed(() => !unref(getSplit) || unref(splitType) !== MenuSplitTyeEnum.LEFT); |
||||
|
|
||||
|
const spiltTop = computed(() => unref(splitType) === MenuSplitTyeEnum.TOP); |
||||
|
|
||||
|
const normalType = computed(() => { |
||||
|
return unref(splitType) === MenuSplitTyeEnum.NONE || !unref(getSplit); |
||||
|
}); |
||||
|
|
||||
|
watch( |
||||
|
[() => unref(currentRoute).path, () => unref(splitType)], |
||||
|
async ([path]: [string, MenuSplitTyeEnum]) => { |
||||
|
if (unref(splitNotLeft)) return; |
||||
|
|
||||
|
const parentPath = await getCurrentParentPath(path); |
||||
|
parentPath && throttleHandleSplitLeftMenu(parentPath); |
||||
|
}, |
||||
|
{ |
||||
|
immediate: true, |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
// Menu changes
|
||||
|
watch( |
||||
|
[() => permissionStore.getLastBuildMenuTimeState, () => permissionStore.getBackMenuListState], |
||||
|
() => { |
||||
|
genMenus(); |
||||
|
}, |
||||
|
{ |
||||
|
immediate: true, |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
// split Menu changes
|
||||
|
watch([() => getSplit.value], () => { |
||||
|
if (unref(splitNotLeft)) return; |
||||
|
genMenus(); |
||||
|
}); |
||||
|
|
||||
|
// Handle left menu split
|
||||
|
async function handleSplitLeftMenu(parentPath: string) { |
||||
|
if (unref(splitLeft)) return; |
||||
|
|
||||
|
// spilt mode left
|
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
// get menus
|
||||
|
async function genMenus() { |
||||
|
// normal mode
|
||||
|
if (unref(normalType)) { |
||||
|
flatMenusRef.value = await getFlatMenus(); |
||||
|
menusRef.value = await getMenus(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// split-top
|
||||
|
if (unref(spiltTop)) { |
||||
|
const shallowMenus = await getShallowMenus(); |
||||
|
|
||||
|
flatMenusRef.value = shallowMenus; |
||||
|
menusRef.value = shallowMenus; |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
return { flatMenusRef, menusRef }; |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
import './index.less'; |
||||
|
|
||||
|
import { computed, defineComponent, ref, unref } from 'vue'; |
||||
|
|
||||
|
import { Layout } from 'ant-design-vue'; |
||||
|
import LayoutMenu from '/@/layouts/default/menu/LayoutMenu'; |
||||
|
|
||||
|
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum'; |
||||
|
|
||||
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
||||
|
import { useTrigger, useDragLine, useSiderEvent } from './useLayoutSider'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'LayoutSideBar', |
||||
|
setup() { |
||||
|
const dragBarRef = ref<Nullable<HTMLDivElement>>(null); |
||||
|
const sideRef = ref<Nullable<HTMLDivElement>>(null); |
||||
|
|
||||
|
const { getCollapsed, getMenuWidth, getSplit, getTheme } = useMenuSetting(); |
||||
|
|
||||
|
const { getTriggerAttr, getTriggerSlot } = useTrigger(); |
||||
|
|
||||
|
const { renderDragLine } = useDragLine(sideRef, dragBarRef); |
||||
|
|
||||
|
const { |
||||
|
getCollapsedWidth, |
||||
|
onBreakpointChange, |
||||
|
onCollapseChange, |
||||
|
onSiderClick, |
||||
|
} = useSiderEvent(); |
||||
|
|
||||
|
const getMode = computed(() => { |
||||
|
return unref(getSplit) ? MenuModeEnum.INLINE : null; |
||||
|
}); |
||||
|
|
||||
|
const getSplitType = computed(() => { |
||||
|
return unref(getSplit) ? MenuSplitTyeEnum.LEFT : MenuSplitTyeEnum.NONE; |
||||
|
}); |
||||
|
|
||||
|
function renderDefault() { |
||||
|
return ( |
||||
|
<> |
||||
|
<LayoutMenu |
||||
|
theme={unref(getTheme)} |
||||
|
menuMode={unref(getMode)} |
||||
|
splitType={unref(getSplitType)} |
||||
|
/> |
||||
|
{renderDragLine()} |
||||
|
</> |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return () => { |
||||
|
return ( |
||||
|
<Layout.Sider |
||||
|
ref={sideRef} |
||||
|
class="layout-sidebar" |
||||
|
breakpoint="md" |
||||
|
collapsible |
||||
|
width={unref(getMenuWidth)} |
||||
|
collapsed={unref(getCollapsed)} |
||||
|
collapsedWidth={unref(getCollapsedWidth)} |
||||
|
theme={unref(getTheme)} |
||||
|
onClick={onSiderClick} |
||||
|
onCollapse={onCollapseChange} |
||||
|
onBreakpoint={onBreakpointChange} |
||||
|
{...unref(getTriggerAttr)} |
||||
|
> |
||||
|
{{ |
||||
|
...unref(getTriggerSlot), |
||||
|
default: () => renderDefault(), |
||||
|
}} |
||||
|
</Layout.Sider> |
||||
|
); |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
@ -0,0 +1,44 @@ |
|||||
|
@import (reference) '../../../design/index.less'; |
||||
|
|
||||
|
.layout-sidebar { |
||||
|
background-size: 100% 100%; |
||||
|
|
||||
|
&.ant-layout-sider-dark { |
||||
|
background: @sider-dark-bg-color; |
||||
|
} |
||||
|
|
||||
|
&:not(.ant-layout-sider-dark) { |
||||
|
border-right: 1px solid @border-color-light; |
||||
|
} |
||||
|
|
||||
|
.ant-layout-sider-zero-width-trigger { |
||||
|
top: 40%; |
||||
|
z-index: 10; |
||||
|
} |
||||
|
|
||||
|
&__darg-bar { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
right: -2px; |
||||
|
z-index: @side-drag-z-index; |
||||
|
width: 2px; |
||||
|
height: 100%; |
||||
|
cursor: col-resize; |
||||
|
border-top: none; |
||||
|
border-bottom: none; |
||||
|
|
||||
|
&.hide { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
&:hover { |
||||
|
background: @primary-color; |
||||
|
box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.15); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.ant-layout-sider-trigger { |
||||
|
height: 36px; |
||||
|
line-height: 36px; |
||||
|
} |
||||
@ -0,0 +1,163 @@ |
|||||
|
import type { Ref } from 'vue'; |
||||
|
|
||||
|
import { computed, unref, onMounted, nextTick, ref } from 'vue'; |
||||
|
import LayoutTrigger from '/@/layouts/default/LayoutTrigger'; |
||||
|
|
||||
|
import { TriggerEnum } from '/@/enums/menuEnum'; |
||||
|
|
||||
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
||||
|
import { useDebounce } from '/@/hooks/core/useDebounce'; |
||||
|
|
||||
|
/** |
||||
|
* Handle related operations of menu events |
||||
|
*/ |
||||
|
export function useSiderEvent() { |
||||
|
const initRef = ref(false); |
||||
|
const brokenRef = ref(false); |
||||
|
const collapseRef = ref(true); |
||||
|
|
||||
|
const { setMenuSetting, getCollapsed, getMiniWidthNumber, getShow } = useMenuSetting(); |
||||
|
|
||||
|
const getCollapsedWidth = computed(() => { |
||||
|
return unref(brokenRef) ? 0 : unref(getMiniWidthNumber); |
||||
|
}); |
||||
|
|
||||
|
function onCollapseChange(val: boolean) { |
||||
|
if (initRef.value) { |
||||
|
collapseRef.value = val; |
||||
|
setMenuSetting({ collapsed: val }); |
||||
|
} else { |
||||
|
!unref(getCollapsed) && setMenuSetting({ collapsed: val }); |
||||
|
} |
||||
|
initRef.value = true; |
||||
|
} |
||||
|
|
||||
|
function onBreakpointChange(broken: boolean) { |
||||
|
brokenRef.value = broken; |
||||
|
} |
||||
|
|
||||
|
function onSiderClick(e: ChangeEvent) { |
||||
|
if (!e || !e.target || e.target.className !== 'basic-menu__content') return; |
||||
|
if (!unref(getCollapsed) || !unref(getShow)) return; |
||||
|
setMenuSetting({ collapsed: false }); |
||||
|
} |
||||
|
return { getCollapsedWidth, onCollapseChange, onBreakpointChange, onSiderClick }; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Handle related operations of menu folding |
||||
|
*/ |
||||
|
export function useTrigger() { |
||||
|
const { getTrigger } = useMenuSetting(); |
||||
|
|
||||
|
const showTrigger = computed(() => { |
||||
|
const trigger = unref(getTrigger); |
||||
|
return trigger !== TriggerEnum.NONE && trigger === TriggerEnum.FOOTER; |
||||
|
}); |
||||
|
|
||||
|
const getTriggerAttr = computed(() => { |
||||
|
if (unref(showTrigger)) { |
||||
|
return {}; |
||||
|
} |
||||
|
return { |
||||
|
trigger: null, |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
const getTriggerSlot = computed(() => { |
||||
|
if (unref(showTrigger)) { |
||||
|
return { |
||||
|
trigger: () => <LayoutTrigger />, |
||||
|
}; |
||||
|
} |
||||
|
return {}; |
||||
|
}); |
||||
|
|
||||
|
return { getTriggerAttr, getTriggerSlot }; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Handle menu drag and drop related operations |
||||
|
* @param siderRef |
||||
|
* @param dragBarRef |
||||
|
*/ |
||||
|
export function useDragLine(siderRef: Ref<any>, dragBarRef: Ref<any>) { |
||||
|
const { getMiniWidthNumber, getCollapsed, setMenuSetting, getHasDrag } = useMenuSetting(); |
||||
|
|
||||
|
const getDragBarStyle = computed(() => { |
||||
|
if (unref(getCollapsed)) { |
||||
|
return { left: `${unref(getMiniWidthNumber)}px` }; |
||||
|
} |
||||
|
return {}; |
||||
|
}); |
||||
|
|
||||
|
onMounted(() => { |
||||
|
nextTick(() => { |
||||
|
const [exec] = useDebounce(changeWrapWidth, 20); |
||||
|
exec(); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
function renderDragLine() { |
||||
|
return ( |
||||
|
<div |
||||
|
class={[`layout-sidebar__darg-bar`, !unref(getHasDrag) ? 'hide' : '']} |
||||
|
style={unref(getDragBarStyle)} |
||||
|
ref={dragBarRef} |
||||
|
/> |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
function handleMouseMove(ele: HTMLElement, wrap: HTMLElement, clientX: number) { |
||||
|
document.onmousemove = function (innerE) { |
||||
|
let iT = (ele as any).left + (innerE.clientX - clientX); |
||||
|
innerE = innerE || window.event; |
||||
|
const maxT = 600; |
||||
|
const minT = unref(getMiniWidthNumber); |
||||
|
iT < 0 && (iT = 0); |
||||
|
iT > maxT && (iT = maxT); |
||||
|
iT < minT && (iT = minT); |
||||
|
ele.style.left = wrap.style.width = iT + 'px'; |
||||
|
return false; |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
// Drag and drop in the menu area-release the mouse
|
||||
|
function removeMouseup(ele: any) { |
||||
|
const wrap = unref(siderRef).$el; |
||||
|
document.onmouseup = function () { |
||||
|
document.onmousemove = null; |
||||
|
document.onmouseup = null; |
||||
|
const width = parseInt(wrap.style.width); |
||||
|
const miniWidth = unref(getMiniWidthNumber); |
||||
|
|
||||
|
if (!unref(getCollapsed)) { |
||||
|
width > miniWidth + 20 |
||||
|
? setMenuSetting({ menuWidth: width }) |
||||
|
: setMenuSetting({ collapsed: true }); |
||||
|
} else { |
||||
|
width > miniWidth && setMenuSetting({ collapsed: false, menuWidth: width }); |
||||
|
} |
||||
|
ele.releaseCapture?.(); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function changeWrapWidth() { |
||||
|
const ele = unref(dragBarRef) as any; |
||||
|
const side = unref(siderRef); |
||||
|
|
||||
|
const wrap = (side || {}).$el; |
||||
|
ele && |
||||
|
(ele.onmousedown = (e: any) => { |
||||
|
wrap.style.transition = 'unset'; |
||||
|
const clientX = e?.clientX; |
||||
|
ele.left = ele.offsetLeft; |
||||
|
handleMouseMove(ele, wrap, clientX); |
||||
|
removeMouseup(ele); |
||||
|
ele.setCapture?.(); |
||||
|
return false; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return { renderDragLine }; |
||||
|
} |
||||
@ -1,105 +0,0 @@ |
|||||
<template> |
|
||||
<div class="app-logo anticon" :class="theme" @click="handleGoHome" :style="wrapStyle"> |
|
||||
<img src="/@/assets/images/logo.png" /> |
|
||||
<div v-if="show" class="logo-title ml-2 ellipsis">{{ globSetting.title }}</div> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script lang="ts"> |
|
||||
import { computed, defineComponent, PropType, ref, watch } from 'vue'; |
|
||||
// hooks |
|
||||
import { useGlobSetting } from '/@/settings/use'; |
|
||||
import { useTimeoutFn } from '/@/hooks/core/useTimeout'; |
|
||||
import { useGo } from '/@/hooks/web/usePage'; |
|
||||
|
|
||||
import { PageEnum } from '/@/enums/pageEnum'; |
|
||||
import { MenuTypeEnum } from '/@/enums/menuEnum'; |
|
||||
|
|
||||
import { menuStore } from '/@/store/modules/menu'; |
|
||||
import { appStore } from '/@/store/modules/app'; |
|
||||
|
|
||||
export default defineComponent({ |
|
||||
name: 'Logo', |
|
||||
props: { |
|
||||
showTitle: { |
|
||||
type: Boolean as PropType<boolean>, |
|
||||
default: true, |
|
||||
}, |
|
||||
theme: { |
|
||||
type: String, |
|
||||
}, |
|
||||
}, |
|
||||
setup(props) { |
|
||||
const showRef = ref<boolean>(!!props.showTitle); |
|
||||
const globSetting = useGlobSetting(); |
|
||||
const go = useGo(); |
|
||||
|
|
||||
function handleGoHome() { |
|
||||
go(PageEnum.BASE_HOME); |
|
||||
} |
|
||||
|
|
||||
watch( |
|
||||
() => props.showTitle, |
|
||||
(show: boolean) => { |
|
||||
if (show) { |
|
||||
useTimeoutFn(() => { |
|
||||
showRef.value = show; |
|
||||
}, 280); |
|
||||
} else { |
|
||||
showRef.value = show; |
|
||||
} |
|
||||
} |
|
||||
); |
|
||||
|
|
||||
const wrapStyle = computed(() => { |
|
||||
const { getCollapsedState } = menuStore; |
|
||||
const { |
|
||||
menuSetting: { menuWidth, type }, |
|
||||
} = appStore.getProjectConfig; |
|
||||
const miniWidth = { minWidth: `${menuWidth}px` }; |
|
||||
if (type !== MenuTypeEnum.SIDEBAR) { |
|
||||
return miniWidth; |
|
||||
} |
|
||||
return getCollapsedState ? {} : miniWidth; |
|
||||
}); |
|
||||
|
|
||||
return { |
|
||||
handleGoHome, |
|
||||
globSetting, |
|
||||
show: showRef, |
|
||||
wrapStyle, |
|
||||
}; |
|
||||
}, |
|
||||
}); |
|
||||
</script> |
|
||||
<style lang="less" scoped> |
|
||||
@import (reference) '../../design/index.less'; |
|
||||
|
|
||||
.app-logo { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding-left: 16px; |
|
||||
cursor: pointer; |
|
||||
// justify-content: center; |
|
||||
&.light { |
|
||||
border-bottom: 1px solid @border-color-base; |
|
||||
} |
|
||||
|
|
||||
.logo-title { |
|
||||
font-size: 18px; |
|
||||
font-weight: 700; |
|
||||
opacity: 0; |
|
||||
transition: all 0.5s; |
|
||||
.respond-to(medium,{ |
|
||||
opacity: 1; |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// &.dark .logo-title { |
|
||||
// font-weight: 400; |
|
||||
// } |
|
||||
|
|
||||
&.light .logo-title { |
|
||||
color: @primary-color; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,67 +0,0 @@ |
|||||
import store from '/@/store'; |
|
||||
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; |
|
||||
import { VuexModule, Module, getModule, Mutation } from 'vuex-module-decorators'; |
|
||||
|
|
||||
import { appStore } from '/@/store/modules/app'; |
|
||||
|
|
||||
const NAME = 'menu'; |
|
||||
hotModuleUnregisterModule(NAME); |
|
||||
@Module({ namespaced: true, name: NAME, dynamic: true, store }) |
|
||||
class Menu extends VuexModule { |
|
||||
// 是否开始拖拽
|
|
||||
private dragStartState = false; |
|
||||
|
|
||||
private currentTopSplitMenuPathState = ''; |
|
||||
|
|
||||
/** |
|
||||
* @description: 获取窗口名称 |
|
||||
*/ |
|
||||
get getCollapsedState() { |
|
||||
return appStore.getProjectConfig.menuSetting.collapsed; |
|
||||
} |
|
||||
|
|
||||
get getCurrentTopSplitMenuPathState() { |
|
||||
return this.currentTopSplitMenuPathState; |
|
||||
} |
|
||||
|
|
||||
get getDragStartState() { |
|
||||
return this.dragStartState; |
|
||||
} |
|
||||
|
|
||||
get getMenuWidthState() { |
|
||||
return appStore.getProjectConfig.menuSetting.menuWidth; |
|
||||
} |
|
||||
|
|
||||
@Mutation |
|
||||
commitDragStartState(dragStart: boolean): void { |
|
||||
this.dragStartState = dragStart; |
|
||||
} |
|
||||
|
|
||||
@Mutation |
|
||||
commitCurrentTopSplitMenuPathState(path: string): void { |
|
||||
this.currentTopSplitMenuPathState = path; |
|
||||
} |
|
||||
|
|
||||
// 改变菜单展开状态
|
|
||||
@Mutation |
|
||||
commitCollapsedState(collapsed: boolean): void { |
|
||||
// this.collapsedState = collapsed;
|
|
||||
appStore.commitProjectConfigState({ |
|
||||
menuSetting: { |
|
||||
collapsed: collapsed, |
|
||||
}, |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
@Mutation |
|
||||
commitMenuWidthState(menuWidth: number): void { |
|
||||
// this.menuWidthState = menuWidth;
|
|
||||
appStore.commitProjectConfigState({ |
|
||||
menuSetting: { |
|
||||
menuWidth: menuWidth, |
|
||||
}, |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export const menuStore = getModule<Menu>(Menu); |
|
||||
Loading…
Reference in new issue