Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
ChenSun1
vue-vben-admin
提交
97180e83
V
vue-vben-admin
项目概览
ChenSun1
/
vue-vben-admin
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vue-vben-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
97180e83
编写于
1月 03, 2021
作者:
V
vben
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(layout): added setting. Used to fix the left mixed mode menu
上级
5091a875
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
192 addition
and
53 deletion
+192
-53
CHANGELOG.zh_CN.md
CHANGELOG.zh_CN.md
+2
-0
package.json
package.json
+1
-1
src/components/Menu/src/BasicMenu.vue
src/components/Menu/src/BasicMenu.vue
+7
-9
src/components/Menu/src/useOpenKeys.ts
src/components/Menu/src/useOpenKeys.ts
+20
-8
src/components/Table/src/hooks/useDataSource.ts
src/components/Table/src/hooks/useDataSource.ts
+1
-1
src/hooks/core/useTimeout.ts
src/hooks/core/useTimeout.ts
+12
-9
src/hooks/setting/useMenuSetting.ts
src/hooks/setting/useMenuSetting.ts
+9
-2
src/layouts/default/setting/SettingDrawer.tsx
src/layouts/default/setting/SettingDrawer.tsx
+7
-0
src/layouts/default/setting/enum.ts
src/layouts/default/setting/enum.ts
+1
-0
src/layouts/default/setting/handler.ts
src/layouts/default/setting/handler.ts
+3
-0
src/layouts/default/sider/MixSider.vue
src/layouts/default/sider/MixSider.vue
+120
-21
src/locales/lang/en/layout/setting.ts
src/locales/lang/en/layout/setting.ts
+2
-0
src/locales/lang/zh_CN/layout/setting.ts
src/locales/lang/zh_CN/layout/setting.ts
+2
-0
src/settings/projectSetting.ts
src/settings/projectSetting.ts
+2
-0
src/types/config.d.ts
src/types/config.d.ts
+1
-0
tsconfig.json
tsconfig.json
+2
-2
未找到文件。
CHANGELOG.zh_CN.md
浏览文件 @
97180e83
...
...
@@ -3,6 +3,8 @@
### ✨ Features
-
新增
`mixSideTrigger`
配置。用于配置左侧混合模式菜单打开方式。可选
`hover`
,默认
`click`
-
新增
`mixSideFixed`
配置。用于固定左侧混合模式菜单
-
modal 组件新增
`height`
和
`min-height`
属性
### 🐛 Bug Fixes
...
...
package.json
浏览文件 @
97180e83
...
...
@@ -7,7 +7,7 @@
"build"
:
"cross-env vite build --mode=production && esno ./build/script/postBuild.ts"
,
"build:site"
:
"cross-env SITE=true npm run build "
,
"build:no-cache"
:
"yarn clean:cache && npm run build"
,
"typecheck"
:
"typecheck ."
,
"typecheck"
:
"
vuedx-
typecheck ."
,
"report"
:
"cross-env REPORT=true npm run build "
,
"preview"
:
"npm run build && esno ./build/script/preview.ts"
,
"preview:dist"
:
"esno ./build/script/preview.ts"
,
...
...
src/components/Menu/src/BasicMenu.vue
浏览文件 @
97180e83
...
...
@@ -125,15 +125,13 @@
}
});
watch
(
()
=>
props
.
items
,
()
=>
{
handleMenuChange
();
}
// {
// immediate: true,
// }
);
!
props
.
mixSider
&&
watch
(
()
=>
props
.
items
,
()
=>
{
handleMenuChange
();
}
);
async
function
handleMenuClick
({
key
,
keyPath
}:
{
key
:
string
;
keyPath
:
string
[]
})
{
const
{
beforeClickFn
}
=
props
;
...
...
src/components/Menu/src/useOpenKeys.ts
浏览文件 @
97180e83
...
...
@@ -8,6 +8,7 @@ import { unref } from 'vue';
import
{
es6Unique
}
from
'
/@/utils
'
;
import
{
useMenuSetting
}
from
'
/@/hooks/setting/useMenuSetting
'
;
import
{
getAllParentPath
}
from
'
/@/router/helper/menuHelper
'
;
import
{
useTimeoutFn
}
from
'
/@/hooks/core/useTimeout
'
;
export
function
useOpenKeys
(
menuState
:
MenuState
,
...
...
@@ -15,18 +16,29 @@ export function useOpenKeys(
mode
:
Ref
<
MenuModeEnum
>
,
accordion
:
Ref
<
boolean
>
)
{
const
{
getCollapsed
,
getIsMixSidebar
}
=
useMenuSetting
();
const
{
getCollapsed
,
getIsMixSidebar
,
getMixSideFixed
}
=
useMenuSetting
();
function
setOpenKeys
(
path
:
string
)
{
async
function
setOpenKeys
(
path
:
string
)
{
if
(
mode
.
value
===
MenuModeEnum
.
HORIZONTAL
)
{
return
;
}
const
menuList
=
toRaw
(
menus
.
value
);
if
(
!
unref
(
accordion
))
{
menuState
.
openKeys
=
es6Unique
([...
menuState
.
openKeys
,
...
getAllParentPath
(
menuList
,
path
)]);
}
else
{
menuState
.
openKeys
=
getAllParentPath
(
menuList
,
path
);
}
const
native
=
unref
(
getIsMixSidebar
)
&&
unref
(
getMixSideFixed
);
useTimeoutFn
(
()
=>
{
const
menuList
=
toRaw
(
menus
.
value
);
if
(
!
unref
(
accordion
))
{
menuState
.
openKeys
=
es6Unique
([
...
menuState
.
openKeys
,
...
getAllParentPath
(
menuList
,
path
),
]);
}
else
{
menuState
.
openKeys
=
getAllParentPath
(
menuList
,
path
);
}
},
16
,
native
);
}
const
getOpenKeys
=
computed
(()
=>
{
...
...
src/components/Table/src/hooks/useDataSource.ts
浏览文件 @
97180e83
...
...
@@ -218,7 +218,7 @@ export function useDataSource(
onMounted
(()
=>
{
useTimeoutFn
(()
=>
{
unref
(
propsRef
).
immediate
&&
fetch
();
},
0
);
},
16
);
});
return
{
...
...
src/hooks/core/useTimeout.ts
浏览文件 @
97180e83
...
...
@@ -3,20 +3,23 @@ import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
import
{
isFunction
}
from
'
/@/utils/is
'
;
export
function
useTimeoutFn
(
handle
:
Fn
<
any
>
,
wait
:
number
)
{
export
function
useTimeoutFn
(
handle
:
Fn
<
any
>
,
wait
:
number
,
native
=
false
)
{
if
(
!
isFunction
(
handle
))
{
throw
new
Error
(
'
handle is not Function!
'
);
}
const
{
readyRef
,
stop
,
start
}
=
useTimeoutRef
(
wait
);
watch
(
readyRef
,
(
maturity
)
=>
{
maturity
&&
handle
();
},
{
immediate
:
false
}
);
if
(
native
)
{
handle
();
}
else
{
watch
(
readyRef
,
(
maturity
)
=>
{
maturity
&&
handle
();
},
{
immediate
:
false
}
);
}
return
{
readyRef
,
stop
,
start
};
}
...
...
src/hooks/setting/useMenuSetting.ts
浏览文件 @
97180e83
import
type
{
MenuSetting
}
from
'
/@/types/config
'
;
import
{
computed
,
unref
}
from
'
vue
'
;
import
{
computed
,
unref
,
ref
}
from
'
vue
'
;
import
{
appStore
}
from
'
/@/store/modules/app
'
;
...
...
@@ -8,6 +8,8 @@ import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appE
import
{
MenuModeEnum
,
MenuTypeEnum
,
TriggerEnum
}
from
'
/@/enums/menuEnum
'
;
import
{
useFullContent
}
from
'
/@/hooks/web/useFullContent
'
;
const
mixSideHasChildren
=
ref
(
false
);
// Get menu configuration
const
getMenuSetting
=
computed
(()
=>
appStore
.
getProjectConfig
.
menuSetting
);
...
...
@@ -39,6 +41,8 @@ const getCanDrag = computed(() => unref(getMenuSetting).canDrag);
const
getAccordion
=
computed
(()
=>
unref
(
getMenuSetting
).
accordion
);
const
getMixSideFixed
=
computed
(()
=>
unref
(
getMenuSetting
).
mixSideFixed
);
const
getTopMenuAlign
=
computed
(()
=>
unref
(
getMenuSetting
).
topMenuAlign
);
const
getCloseMixSidebarOnChange
=
computed
(()
=>
unref
(
getMenuSetting
).
closeMixSidebarOnChange
);
...
...
@@ -87,7 +91,8 @@ const getCalcContentWidth = computed(() => {
unref
(
getIsTopMenu
)
||
!
unref
(
getShowMenu
)
||
(
unref
(
getSplit
)
&&
unref
(
getMenuHidden
))
?
0
:
unref
(
getIsMixSidebar
)
?
SIDE_BAR_SHOW_TIT_MINI_WIDTH
?
SIDE_BAR_SHOW_TIT_MINI_WIDTH
+
(
unref
(
getMixSideFixed
)
&&
unref
(
mixSideHasChildren
)
?
unref
(
getRealWidth
)
:
0
)
:
unref
(
getRealWidth
);
return
`calc(100% -
${
unref
(
width
)}
px)`
;
...
...
@@ -148,5 +153,7 @@ export function useMenuSetting() {
getIsMixSidebar
,
getCloseMixSidebarOnChange
,
getMixSideTrigger
,
getMixSideFixed
,
mixSideHasChildren
,
};
}
src/layouts/default/setting/SettingDrawer.tsx
浏览文件 @
97180e83
...
...
@@ -75,6 +75,7 @@ export default defineComponent({
getIsMixSidebar
,
getCloseMixSidebarOnChange
,
getMixSideTrigger
,
getMixSideFixed
,
}
=
useMenuSetting
();
const
{
...
...
@@ -110,6 +111,12 @@ export default defineComponent({
def
=
{
unref
(
getSplit
)
}
disabled
=
{
!
unref
(
getShowMenuRef
)
||
unref
(
getMenuType
)
!==
MenuTypeEnum
.
MIX
}
/>
<
SwitchItem
title
=
{
t
(
'
layout.setting.mixSidebarFixed
'
)
}
event
=
{
HandlerEnum
.
MENU_FIXED_MIX_SIDEBAR
}
def
=
{
unref
(
getMixSideFixed
)
}
disabled
=
{
!
unref
(
getIsMixSidebar
)
}
/>
<
SwitchItem
title
=
{
t
(
'
layout.setting.closeMixSidebarOnChange
'
)
}
...
...
src/layouts/default/setting/enum.ts
浏览文件 @
97180e83
...
...
@@ -27,6 +27,7 @@ export enum HandlerEnum {
MENU_FIXED
,
MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE
,
MENU_TRIGGER_MIX_SIDEBAR
,
MENU_FIXED_MIX_SIDEBAR
,
// header
HEADER_SHOW
,
...
...
src/layouts/default/setting/handler.ts
浏览文件 @
97180e83
...
...
@@ -70,6 +70,9 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf
case
HandlerEnum
.
MENU_TRIGGER_MIX_SIDEBAR
:
return
{
menuSetting
:
{
mixSideTrigger
:
value
}
};
case
HandlerEnum
.
MENU_FIXED_MIX_SIDEBAR
:
return
{
menuSetting
:
{
mixSideTrigger
:
value
}
};
// ============transition==================
case
HandlerEnum
.
OPEN_PAGE_LOADING
:
appStore
.
commitPageLoadingState
(
false
);
...
...
src/layouts/default/sider/MixSider.vue
浏览文件 @
97180e83
<
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-i
con
<
I
con
: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.
2
s ease 0s;
transition: all 0.
3
s 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: s
tart
;
justify-content: s
pace-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 {
...
...
src/locales/lang/en/layout/setting.ts
浏览文件 @
97180e83
...
...
@@ -77,4 +77,6 @@ export default {
mixSidebarTrigger
:
'
Mixed menu Trigger
'
,
triggerHover
:
'
Hover
'
,
triggerClick
:
'
Click
'
,
mixSidebarFixed
:
'
Fixed expanded menu
'
,
};
src/locales/lang/zh_CN/layout/setting.ts
浏览文件 @
97180e83
...
...
@@ -76,4 +76,6 @@ export default {
mixSidebarTrigger
:
'
混合菜单触发方式
'
,
triggerHover
:
'
悬停
'
,
triggerClick
:
'
点击
'
,
mixSidebarFixed
:
'
固定展开菜单
'
,
};
src/settings/projectSetting.ts
浏览文件 @
97180e83
...
...
@@ -110,6 +110,8 @@ const setting: ProjectConfig = {
closeMixSidebarOnChange
:
false
,
// Module opening method ‘click’ |'hover'
mixSideTrigger
:
MixSidebarTriggerEnum
.
CLICK
,
// Fixed expanded menu
mixSideFixed
:
false
,
},
// Multi-label
...
...
src/types/config.d.ts
浏览文件 @
97180e83
...
...
@@ -21,6 +21,7 @@ export interface MenuSetting {
closeMixSidebarOnChange
:
boolean
;
collapsedShowTitle
:
boolean
;
mixSideTrigger
:
MixSidebarTriggerEnum
;
mixSideFixed
:
boolean
;
}
export
interface
MultiTabsSetting
{
...
...
tsconfig.json
浏览文件 @
97180e83
{
"compilerOptions"
:
{
"target"
:
"es
2016
"
,
"target"
:
"es
next
"
,
"module"
:
"esnext"
,
"moduleResolution"
:
"node"
,
"strict"
:
true
,
"forceConsistentCasingInFileNames"
:
true
,
"allowSyntheticDefaultImports"
:
true
,
"strictFunctionTypes"
:
false
,
"jsx"
:
"
react
"
,
"jsx"
:
"
preserve
"
,
"baseUrl"
:
"."
,
"allowJs"
:
true
,
"sourceMap"
:
true
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录