Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
ChenSun1
vue-vben-admin
提交
cbcd9098
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,发现更多精彩内容 >>
提交
cbcd9098
编写于
12月 14, 2020
作者:
V
vben
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip(menu): perf menu
上级
f81c4019
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
424 addition
and
364 deletion
+424
-364
src/components/Application/src/AppLogo.vue
src/components/Application/src/AppLogo.vue
+2
-1
src/components/Menu/index.ts
src/components/Menu/index.ts
+3
-1
src/components/Menu/src/BasicMenu.tsx
src/components/Menu/src/BasicMenu.tsx
+0
-267
src/components/Menu/src/BasicMenu.vue
src/components/Menu/src/BasicMenu.vue
+209
-0
src/components/Menu/src/components/BasicMenuItem.vue
src/components/Menu/src/components/BasicMenuItem.vue
+39
-0
src/components/Menu/src/components/BasicSubMenuItem.vue
src/components/Menu/src/components/BasicSubMenuItem.vue
+53
-0
src/components/Menu/src/components/ExpandIcon.vue
src/components/Menu/src/components/ExpandIcon.vue
+43
-0
src/components/Menu/src/helper.ts
src/components/Menu/src/helper.ts
+0
-12
src/components/Menu/src/index.less
src/components/Menu/src/index.less
+42
-41
src/components/Menu/src/props.ts
src/components/Menu/src/props.ts
+22
-32
src/components/Menu/src/types.ts
src/components/Menu/src/types.ts
+6
-6
src/enums/appEnum.ts
src/enums/appEnum.ts
+1
-1
src/layouts/default/tabs/index.less
src/layouts/default/tabs/index.less
+3
-3
src/router/helper/menuHelper.ts
src/router/helper/menuHelper.ts
+1
-0
未找到文件。
src/components/Application/src/AppLogo.vue
浏览文件 @
cbcd9098
...
...
@@ -66,8 +66,9 @@
.@{prefix-cls} {
display: flex;
align-items: center;
padding-left:
12
px;
padding-left:
7
px;
cursor: pointer;
transition: all 0.2s ease;
&.collapsed-show-title {
padding-left: 20px;
...
...
src/components/Menu/index.ts
浏览文件 @
cbcd9098
...
...
@@ -2,6 +2,8 @@ import { withInstall } from '../util';
import
{
createAsyncComponent
}
from
'
/@/utils/factory/createAsyncComponent
'
;
export
const
BasicMenu
=
createAsyncComponent
(()
=>
import
(
'
./src/BasicMenu
'
),
{
loading
:
false
});
export
const
BasicMenu
=
createAsyncComponent
(()
=>
import
(
'
./src/BasicMenu.vue
'
),
{
loading
:
false
,
});
withInstall
(
BasicMenu
);
src/components/Menu/src/BasicMenu.tsx
已删除
100644 → 0
浏览文件 @
f81c4019
import
'
./index.less
'
;
import
type
{
MenuState
}
from
'
./types
'
;
import
type
{
Menu
as
MenuType
}
from
'
/@/router/types
'
;
import
{
computed
,
defineComponent
,
unref
,
reactive
,
watch
,
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
'
;
import
{
appStore
}
from
'
/@/store/modules/app
'
;
import
{
useOpenKeys
}
from
'
./useOpenKeys
'
;
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
:
[],
mode
:
props
.
mode
,
theme
:
computed
(()
=>
props
.
theme
)
as
ComputedRef
<
ThemeEnum
>
,
openKeys
:
[],
selectedKeys
:
[],
collapsedOpenKeys
:
[],
});
const
{
prefixCls
}
=
useDesign
(
'
basic-menu
'
);
const
{
items
,
mode
,
accordion
}
=
toRefs
(
props
);
const
{
getCollapsed
,
getIsHorizontal
,
getTopMenuAlign
,
getSplit
}
=
useMenuSetting
();
const
{
currentRoute
}
=
useRouter
();
const
{
handleOpenChange
,
setOpenKeys
,
getOpenKeys
}
=
useOpenKeys
(
menuState
,
items
,
mode
,
accordion
);
const
getMenuClass
=
computed
(()
=>
{
const
{
type
}
=
props
;
const
{
mode
}
=
menuState
;
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
)
||
getSplit
.
value
;
return
{
height
:
isHorizontal
?
'
100%
'
:
`calc(100% -
${
props
.
showLogo
?
'
48px
'
:
'
0px
'
}
)`
,
overflowY
:
isHorizontal
?
'
hidden
'
:
'
auto
'
,
};
}
);
watch
(
()
=>
tabStore
.
getCurrentTab
,
()
=>
{
if
(
unref
(
currentRoute
).
name
===
REDIRECT_NAME
)
return
;
handleMenuChange
();
unref
(
getSplit
)
&&
getParentPath
();
}
);
watch
(
()
=>
props
.
items
,
()
=>
{
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
({
key
,
keyPath
}:
{
key
:
string
;
keyPath
:
string
[]
})
{
const
{
beforeClickFn
}
=
props
;
if
(
beforeClickFn
&&
isFunction
(
beforeClickFn
))
{
const
flag
=
await
beforeClickFn
(
key
);
if
(
!
flag
)
return
;
}
emit
(
'
menuClick
'
,
key
);
isClickGo
.
value
=
true
;
menuState
.
openKeys
=
keyPath
;
menuState
.
selectedKeys
=
[
key
];
}
function
handleMenuChange
()
{
if
(
unref
(
isClickGo
))
{
isClickGo
.
value
=
false
;
return
;
}
const
path
=
unref
(
currentRoute
).
path
;
if
(
menuState
.
mode
!==
MenuModeEnum
.
HORIZONTAL
)
{
setOpenKeys
(
path
);
}
menuState
.
selectedKeys
=
[
path
];
}
// 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,
// },
// ]}
// />
// );
// }
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
{
selectedKeys
,
defaultSelectedKeys
,
mode
,
theme
}
=
menuState
;
return
(
<
Menu
selectedKeys
=
{
selectedKeys
}
defaultSelectedKeys
=
{
defaultSelectedKeys
}
mode
=
{
mode
}
openKeys
=
{
unref
(
getOpenKeys
)
}
inlineIndent
=
{
props
.
inlineIndent
}
theme
=
{
unref
(
theme
)
}
onOpenChange
=
{
handleOpenChange
}
class
=
{
unref
(
getMenuClass
)
}
onClick
=
{
handleMenuClick
}
subMenuOpenDelay
=
{
0.2
}
{
...
unref
(
getInlineCollapseOptions
)
}
>
{
{
default
:
()
=>
unref
(
items
).
map
((
item
)
=>
renderItem
(
item
)),
}
}
</
Menu
>
);
}
return
()
=>
{
return
(
<>
{
!
unref
(
getIsHorizontal
)
&&
getSlot
(
slots
,
'
header
'
)
}
<
div
class
=
{
`
${
prefixCls
}
-wrapper`
}
style
=
{
unref
(
getWrapperStyle
)
}
>
{
renderMenu
()
}
</
div
>
</>
);
};
},
});
src/components/Menu/src/BasicMenu.vue
0 → 100644
浏览文件 @
cbcd9098
<
template
>
<slot
name=
"header"
v-if=
"!getIsHorizontal"
/>
<ScrollContainer
:class=
"`$
{prefixCls}-wrapper`" :style="getWrapperStyle">
<Menu
:selectedKeys=
"selectedKeys"
:defaultSelectedKeys=
"defaultSelectedKeys"
:mode=
"mode"
:openKeys=
"getOpenKeys"
:inlineIndent=
"inlineIndent"
:theme=
"theme"
@
openChange=
"handleOpenChange"
:class=
"getMenuClass"
@
click=
"handleMenuClick"
:subMenuOpenDelay=
"0.2"
v-bind=
"getInlineCollapseOptions"
>
<template
v-for=
"item in items"
:key=
"item.path"
>
<BasicSubMenuItem
:item=
"item"
:theme=
"theme"
:level=
"1"
:appendClass=
"appendClass"
:parentPath=
"currentParentPath"
:showTitle=
"showTitle"
:isHorizontal=
"isHorizontal"
/>
</
template
>
</Menu>
</ScrollContainer>
</template>
<
script
lang=
"ts"
>
import
type
{
MenuState
}
from
'
./types
'
;
import
{
computed
,
defineComponent
,
unref
,
reactive
,
watch
,
toRefs
,
ref
,
CSSProperties
,
}
from
'
vue
'
;
import
{
Menu
}
from
'
ant-design-vue
'
;
import
BasicSubMenuItem
from
'
./components/BasicSubMenuItem.vue
'
;
import
{
ScrollContainer
}
from
'
/@/components/Container
'
;
import
{
MenuModeEnum
,
MenuTypeEnum
}
from
'
/@/enums/menuEnum
'
;
import
{
appStore
}
from
'
/@/store/modules/app
'
;
import
{
useOpenKeys
}
from
'
./useOpenKeys
'
;
import
{
useRouter
}
from
'
vue-router
'
;
import
{
isFunction
}
from
'
/@/utils/is
'
;
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
'
;
// import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
export
default
defineComponent
({
name
:
'
BasicMenu
'
,
components
:
{
Menu
,
ScrollContainer
,
BasicSubMenuItem
,
// BasicSubMenuItem: createAsyncComponent(() => import('./components/BasicSubMenuItem.vue')),
},
props
:
basicProps
,
emits
:
[
'
menuClick
'
],
setup
(
props
,
{
emit
})
{
const
currentParentPath
=
ref
(
''
);
const
isClickGo
=
ref
(
false
);
const
menuState
=
reactive
<
MenuState
>
({
defaultSelectedKeys
:
[],
openKeys
:
[],
selectedKeys
:
[],
collapsedOpenKeys
:
[],
});
const
{
prefixCls
}
=
useDesign
(
'
basic-menu
'
);
const
{
items
,
mode
,
accordion
}
=
toRefs
(
props
);
const
{
getCollapsed
,
getIsHorizontal
,
getTopMenuAlign
,
getSplit
}
=
useMenuSetting
();
const
{
currentRoute
}
=
useRouter
();
const
{
handleOpenChange
,
setOpenKeys
,
getOpenKeys
}
=
useOpenKeys
(
menuState
,
items
,
mode
,
accordion
);
const
getMenuClass
=
computed
(()
=>
{
const
{
type
,
mode
}
=
props
;
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
=>
{
return
{
height
:
`calc(100% -
${
props
.
showLogo
?
'
48px
'
:
'
0px
'
}
)`
,
overflowY
:
'
hidden
'
,
};
}
);
watch
(
()
=>
tabStore
.
getCurrentTab
,
()
=>
{
if
(
unref
(
currentRoute
).
name
===
REDIRECT_NAME
)
return
;
handleMenuChange
();
unref
(
getSplit
)
&&
getParentPath
();
}
);
watch
(
()
=>
props
.
items
,
()
=>
{
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
({
key
,
keyPath
}:
{
key
:
string
;
keyPath
:
string
[]
})
{
const
{
beforeClickFn
}
=
props
;
if
(
beforeClickFn
&&
isFunction
(
beforeClickFn
))
{
const
flag
=
await
beforeClickFn
(
key
);
if
(
!
flag
)
return
;
}
emit
(
'
menuClick
'
,
key
);
isClickGo
.
value
=
true
;
menuState
.
openKeys
=
keyPath
;
menuState
.
selectedKeys
=
[
key
];
}
function
handleMenuChange
()
{
if
(
unref
(
isClickGo
))
{
isClickGo
.
value
=
false
;
return
;
}
const
path
=
unref
(
currentRoute
).
path
;
if
(
props
.
mode
!==
MenuModeEnum
.
HORIZONTAL
)
{
setOpenKeys
(
path
);
}
menuState
.
selectedKeys
=
[
path
];
}
return
{
prefixCls
,
getIsHorizontal
,
getWrapperStyle
,
handleMenuClick
,
getInlineCollapseOptions
,
getMenuClass
,
handleOpenChange
,
getOpenKeys
,
currentParentPath
,
showTitle
,
...
toRefs
(
menuState
),
};
},
});
</
script
>
<
style
lang=
"less"
>
@import './index.less';
</
style
>
src/components/Menu/src/components/BasicMenuItem.vue
0 → 100644
浏览文件 @
cbcd9098
<
template
>
<MenuItem
:class=
"getLevelClass"
>
<MenuContent
v-bind=
"$props"
:item=
"item"
/>
</MenuItem>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
,
computed
}
from
'
vue
'
;
import
{
Menu
}
from
'
ant-design-vue
'
;
import
{
useDesign
}
from
'
/@/hooks/web/useDesign
'
;
import
{
itemProps
}
from
'
../props
'
;
import
MenuContent
from
'
../MenuContent
'
;
export
default
defineComponent
({
name
:
'
BasicMenuItem
'
,
components
:
{
MenuItem
:
Menu
.
Item
,
MenuContent
},
props
:
itemProps
,
setup
(
props
)
{
const
{
prefixCls
}
=
useDesign
(
'
basic-menu-item
'
);
const
getLevelClass
=
computed
(()
=>
{
const
{
appendClass
,
level
,
item
,
parentPath
,
theme
}
=
props
;
const
isAppendActiveCls
=
appendClass
&&
level
===
1
&&
item
.
path
===
parentPath
;
const
levelCls
=
[
`
${
prefixCls
}
__level
${
level
}
`
,
theme
,
{
'
top-active-menu
'
:
isAppendActiveCls
,
},
];
return
levelCls
;
});
return
{
prefixCls
,
getLevelClass
,
};
},
});
</
script
>
src/components/Menu/src/components/BasicSubMenuItem.vue
0 → 100644
浏览文件 @
cbcd9098
<
template
>
<BasicMenuItem
v-if=
"!menuHasChildren(item)"
v-bind=
"$props"
/>
<SubMenu
v-else
:class=
"[`$
{prefixCls}__level${level}`, theme]">
<template
#title
>
<MenuContent
v-bind=
"$props"
:item=
"item"
/>
</
template
>
<!-- <template #expandIcon="{ key }">
<ExpandIcon :key="key" />
</template> -->
<
template
v-for=
"childrenItem in item.children || []"
:key=
"childrenItem.path"
>
<BasicSubMenuItem
v-bind=
"$props"
:item=
"childrenItem"
:level=
"level + 1"
/>
</
template
>
</SubMenu>
</template>
<
script
lang=
"ts"
>
import
type
{
Menu
as
MenuType
}
from
'
/@/router/types
'
;
import
{
defineComponent
}
from
'
vue
'
;
import
{
Menu
}
from
'
ant-design-vue
'
;
import
{
useDesign
}
from
'
/@/hooks/web/useDesign
'
;
import
{
itemProps
}
from
'
../props
'
;
import
BasicMenuItem
from
'
./BasicMenuItem.vue
'
;
import
MenuContent
from
'
../MenuContent
'
;
// import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
export
default
defineComponent
({
name
:
'
BasicSubMenuItem
'
,
components
:
{
BasicMenuItem
,
SubMenu
:
Menu
.
SubMenu
,
MenuItem
:
Menu
.
Item
,
MenuContent
,
// ExpandIcon: createAsyncComponent(() => import('./ExpandIcon.vue')),
},
props
:
itemProps
,
setup
()
{
const
{
prefixCls
}
=
useDesign
(
'
basic-menu-item
'
);
function
menuHasChildren
(
menuTreeItem
:
MenuType
):
boolean
{
return
(
Reflect
.
has
(
menuTreeItem
,
'
children
'
)
&&
!!
menuTreeItem
.
children
&&
menuTreeItem
.
children
.
length
>
0
);
}
return
{
prefixCls
,
menuHasChildren
,
};
},
});
</
script
>
src/components/Menu/src/components/ExpandIcon.vue
0 → 100644
浏览文件 @
cbcd9098
<
template
>
<BasicArrow
:expand=
"getIsOpen"
bottom
inset
:class=
"getWrapperClass"
/>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
,
PropType
,
computed
}
from
'
vue
'
;
import
{
useDesign
}
from
'
/@/hooks/web/useDesign
'
;
import
{
BasicArrow
}
from
'
/@/components/Basic
'
;
import
{
propTypes
}
from
'
/@/utils/propTypes
'
;
export
default
defineComponent
({
name
:
'
BasicMenuItem
'
,
components
:
{
BasicArrow
},
props
:
{
key
:
propTypes
.
string
,
openKeys
:
{
type
:
Array
as
PropType
<
string
[]
>
,
default
:
[],
},
collapsed
:
propTypes
.
bool
,
},
setup
(
props
)
{
const
{
prefixCls
}
=
useDesign
(
'
basic-menu
'
);
const
getIsOpen
=
computed
(()
=>
{
return
props
.
openKeys
.
includes
(
props
.
key
);
});
const
getWrapperClass
=
computed
(()
=>
{
return
[
`
${
prefixCls
}
__expand-icon`
,
{
[
`
${
prefixCls
}
__expand-icon--collapsed`
]:
props
.
collapsed
,
},
];
});
return
{
prefixCls
,
getIsOpen
,
getWrapperClass
,
};
},
});
</
script
>
src/components/Menu/src/helper.ts
已删除
100644 → 0
浏览文件 @
f81c4019
import
type
{
Menu
as
MenuType
}
from
'
/@/router/types
'
;
/**
* @description: Whether the menu has child nodes
*/
export
function
menuHasChildren
(
menuTreeItem
:
MenuType
):
boolean
{
return
(
Reflect
.
has
(
menuTreeItem
,
'
children
'
)
&&
!!
menuTreeItem
.
children
&&
menuTreeItem
.
children
.
length
>
0
);
}
src/components/Menu/src/index.less
浏览文件 @
cbcd9098
...
...
@@ -4,6 +4,7 @@
.active-style() {
color: @white;
// background: @primary-color !important;
background: linear-gradient(
118deg,
rgba(@primary-color, 0.8),
...
...
@@ -27,6 +28,7 @@
// right: 16px;
// width: 10px;
// transform-origin: none;
// opacity: 0.45;
// span[role='img'] {
// margin-right: 0;
...
...
@@ -52,9 +54,9 @@
> .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:
20
px !important;
padding-left:
20
px !important;
&.ant-menu-inline-collapsed .ant-menu-submenu-title {
padding-right:
16
px !important;
padding-left:
16
px !important;
}
}
...
...
@@ -87,32 +89,33 @@
}
}
//
.ant-menu-item {
//
transition: unset;
//
}
.ant-menu-item {
transition: unset;
}
// scrollbar -s tart
&-wrapper {
/* 滚动槽 */
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}
// &-wrapper {
&::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0);
}
/* 滚动槽 */
// &::-webkit-scrollbar {
// width: 5px;
// height: 5px;
// }
&::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.2);
border-radius: 3px;
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
}
// &::-webkit-scrollbar-track {
// background: rgba(0, 0, 0, 0);
// }
::-webkit-scrollbar-thumb:hover {
background: @border-color-dark;
}
}
// &::-webkit-scrollbar-thumb {
// background: rgba(255, 255, 255, 0.2);
// border-radius: 3px;
// box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
// }
// ::-webkit-scrollbar-thumb:hover {
// background: @border-color-dark;
// }
// }
// scrollbar end
...
...
@@ -225,14 +228,6 @@
}
}
&: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-prefix-cls}__sidebar-hor):not(.@{basic-menu-prefix-cls}__second) {
// Reset menu item row height
.ant-menu-item:not(.@{basic-menu-prefix-cls}-item__level1),
...
...
@@ -255,10 +250,6 @@
background: @sider-dark-bg-color;
.active-menu-style();
// .menu-item-icon.app-iconify {
// display: inline-block !important;
// }
.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;
...
...
@@ -304,10 +295,6 @@
overflow: hidden;
border-right: none;
// .menu-item-icon.app-iconify {
// display: inline-block !important;
// }
.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;
...
...
@@ -332,6 +319,7 @@
align-items: center;
}
}
.@{basic-menu-prefix-cls}__tag {
position: absolute;
top: calc(50% - 8px);
...
...
@@ -368,6 +356,20 @@
background: @warning-color;
}
}
.ant-menu-submenu,
.ant-menu-submenu-inline {
transition: unset;
}
// .ant-menu-submenu-arrow {
// transition: all 0.15s ease 0s;
// }
.ant-menu-inline.ant-menu-sub {
box-shadow: unset !important;
transition: unset;
}
}
.ant-menu-dark {
...
...
@@ -375,7 +377,6 @@
> ul {
background: @sider-dark-bg-color;
}
.active-menu-style();
}
}
...
...
src/components/Menu/src/props.ts
浏览文件 @
cbcd9098
...
...
@@ -3,57 +3,47 @@ import type { PropType } from 'vue';
import
{
MenuModeEnum
,
MenuTypeEnum
}
from
'
/@/enums/menuEnum
'
;
import
{
ThemeEnum
}
from
'
/@/enums/appEnum
'
;
import
{
propTypes
}
from
'
/@/utils/propTypes
'
;
export
const
basicProps
=
{
items
:
{
type
:
Array
as
PropType
<
Menu
[]
>
,
default
:
()
=>
[],
},
appendClass
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
appendClass
:
propTypes
.
bool
,
collapsedShowTitle
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
collapsedShowTitle
:
propTypes
.
bool
,
// 最好是4 倍数
inlineIndent
:
{
type
:
Number
as
PropType
<
number
>
,
default
:
20
,
},
inlineIndent
:
propTypes
.
number
.
def
(
20
),
// 菜单组件的mode属性
mode
:
{
type
:
String
as
PropType
<
MenuModeEnum
>
,
default
:
MenuModeEnum
.
INLINE
,
},
showLogo
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
showLogo
:
propTypes
.
bool
,
type
:
{
type
:
String
as
PropType
<
MenuTypeEnum
>
,
default
:
MenuTypeEnum
.
MIX
,
},
theme
:
{
type
:
String
as
PropType
<
string
>
,
default
:
ThemeEnum
.
DARK
,
},
inlineCollapsed
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
theme
:
propTypes
.
string
.
def
(
ThemeEnum
.
DARK
),
inlineCollapsed
:
propTypes
.
bool
,
isHorizontal
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
accordion
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
isHorizontal
:
propTypes
.
bool
,
accordion
:
propTypes
.
bool
.
def
(
true
),
beforeClickFn
:
{
type
:
Function
as
PropType
<
(
key
:
string
)
=>
Promise
<
boolean
>>
,
},
};
export
const
itemProps
=
{
item
:
{
type
:
Object
as
PropType
<
Menu
>
,
default
:
{},
},
level
:
propTypes
.
number
,
theme
:
propTypes
.
oneOf
([
'
dark
'
,
'
light
'
]),
appendClass
:
propTypes
.
bool
,
parentPath
:
propTypes
.
string
,
showTitle
:
propTypes
.
bool
,
isHorizontal
:
propTypes
.
bool
,
};
src/components/Menu/src/types.ts
浏览文件 @
cbcd9098
import
{
ComputedRef
}
from
'
vue
'
;
import
{
ThemeEnum
}
from
'
/@/enums/appEnum
'
;
import
{
MenuModeEnum
}
from
'
/@/enums/menuEnum
'
;
//
import { ComputedRef } from 'vue';
//
import { ThemeEnum } from '/@/enums/appEnum';
//
import { MenuModeEnum } from '/@/enums/menuEnum';
export
interface
MenuState
{
// 默认选中的列表
defaultSelectedKeys
:
string
[];
// 模式
mode
:
MenuModeEnum
;
//
mode: MenuModeEnum;
// 主题
theme
:
ComputedRef
<
ThemeEnum
>
|
ThemeEnum
;
//
//
主题
//
theme: ComputedRef<ThemeEnum> | ThemeEnum;
// 缩进
inlineIndent
?:
number
;
...
...
src/enums/appEnum.ts
浏览文件 @
cbcd9098
export
const
SIDE_BAR_MINI_WIDTH
=
5
8
;
export
const
SIDE_BAR_MINI_WIDTH
=
4
8
;
export
const
SIDE_BAR_SHOW_TIT_MINI_WIDTH
=
80
;
export
enum
ContentEnum
{
...
...
src/layouts/default/tabs/index.less
浏览文件 @
cbcd9098
...
...
@@ -34,9 +34,9 @@
border: 1px solid darken(@border-color-light, 6%);
transition: none;
&:not(.ant-tabs-tab-active)::
before
{
&:not(.ant-tabs-tab-active)::
after
{
position: absolute;
top
: -1px;
bottom
: -1px;
left: 50%;
width: 100%;
height: 2px;
...
...
@@ -53,7 +53,7 @@
opacity: 1;
}
&:not(.ant-tabs-tab-active)::
before
{
&:not(.ant-tabs-tab-active)::
after
{
opacity: 1;
transform: translate(-50%, 0) scaleX(1);
transition: all 0.3s ease-in-out;
...
...
src/router/helper/menuHelper.ts
浏览文件 @
cbcd9098
...
...
@@ -42,6 +42,7 @@ export function transformMenuModule(menuModule: MenuModule): Menu {
forEach(menuList, (m) => {
!isUrl(m.path) && joinParentPath(menuList, m);
});
return menuList[0];
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录