Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-vue-admin
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-vue-admin
Commits
cbcd9098
提交
cbcd9098
authored
12月 14, 2020
作者:
vben
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip(menu): perf menu
上级
f81c4019
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
215 行增加
和
97 行删除
+215
-97
AppLogo.vue
src/components/Application/src/AppLogo.vue
+2
-1
index.ts
src/components/Menu/index.ts
+3
-1
BasicMenu.vue
src/components/Menu/src/BasicMenu.vue
+0
-0
BasicMenuItem.vue
src/components/Menu/src/components/BasicMenuItem.vue
+39
-0
BasicSubMenuItem.vue
src/components/Menu/src/components/BasicSubMenuItem.vue
+53
-0
ExpandIcon.vue
src/components/Menu/src/components/ExpandIcon.vue
+43
-0
helper.ts
src/components/Menu/src/helper.ts
+0
-12
index.less
src/components/Menu/src/index.less
+42
-41
props.ts
src/components/Menu/src/props.ts
+22
-32
types.ts
src/components/Menu/src/types.ts
+6
-6
appEnum.ts
src/enums/appEnum.ts
+1
-1
index.less
src/layouts/default/tabs/index.less
+3
-3
menuHelper.ts
src/router/helper/menuHelper.ts
+1
-0
没有找到文件。
src/components/Application/src/AppLogo.vue
浏览文件 @
cbcd9098
...
@@ -66,8 +66,9 @@
...
@@ -66,8 +66,9 @@
.@
{
prefix-cls
}
{
.@
{
prefix-cls
}
{
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
padding-left
:
12
px
;
padding-left
:
7
px
;
cursor
:
pointer
;
cursor
:
pointer
;
transition
:
all
0.2s
ease
;
&.collapsed-show-title
{
&.collapsed-show-title
{
padding-left
:
20px
;
padding-left
:
20px
;
...
...
src/components/Menu/index.ts
浏览文件 @
cbcd9098
...
@@ -2,6 +2,8 @@ import { withInstall } from '../util';
...
@@ -2,6 +2,8 @@ import { withInstall } from '../util';
import
{
createAsyncComponent
}
from
'/@/utils/factory/createAsyncComponent'
;
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
);
withInstall
(
BasicMenu
);
src/components/Menu/src/BasicMenu.
tsx
→
src/components/Menu/src/BasicMenu.
vue
浏览文件 @
cbcd9098
差异被折叠。
点击展开。
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
deleted
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 @@
...
@@ -4,6 +4,7 @@
.active-style() {
.active-style() {
color: @white;
color: @white;
// background: @primary-color !important;
background: linear-gradient(
background: linear-gradient(
118deg,
118deg,
rgba(@primary-color, 0.8),
rgba(@primary-color, 0.8),
...
@@ -27,6 +28,7 @@
...
@@ -27,6 +28,7 @@
// right: 16px;
// right: 16px;
// width: 10px;
// width: 10px;
// transform-origin: none;
// transform-origin: none;
// opacity: 0.45;
// span[role='img'] {
// span[role='img'] {
// margin-right: 0;
// margin-right: 0;
...
@@ -52,9 +54,9 @@
...
@@ -52,9 +54,9 @@
> .ant-menu-item-group-list
> .ant-menu-item-group-list
> .ant-menu-submenu
> .ant-menu-submenu
> .ant-menu-submenu-title,
> .ant-menu-submenu-title,
&.ant-menu-inline-collapsed
> .ant-menu-submenu >
.ant-menu-submenu-title {
&.ant-menu-inline-collapsed .ant-menu-submenu-title {
padding-right:
20
px !important;
padding-right:
16
px !important;
padding-left:
20
px !important;
padding-left:
16
px !important;
}
}
}
}
...
@@ -87,32 +89,33 @@
...
@@ -87,32 +89,33 @@
}
}
}
}
//
.ant-menu-item {
.ant-menu-item {
//
transition: unset;
transition: unset;
//
}
}
// scrollbar -s tart
// scrollbar -s tart
&-wrapper {
// &-wrapper {
/* 滚动槽 */
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-track {
/* 滚动槽 */
background: rgba(0, 0, 0, 0);
// &::-webkit-scrollbar {
}
// width: 5px;
// height: 5px;
// }
&::-webkit-scrollbar-thumb {
// &::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.2);
// background: rgba(0, 0, 0, 0);
border-radius: 3px;
// }
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
}
::-webkit-scrollbar-thumb:hover {
// &::-webkit-scrollbar-thumb {
background: @border-color-dark;
// 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
// scrollbar end
...
@@ -225,14 +228,6 @@
...
@@ -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) {
&.ant-menu-dark:not(.@{basic-menu-prefix-cls}__sidebar-hor):not(.@{basic-menu-prefix-cls}__second) {
// Reset menu item row height
// Reset menu item row height
.ant-menu-item:not(.@{basic-menu-prefix-cls}-item__level1),
.ant-menu-item:not(.@{basic-menu-prefix-cls}-item__level1),
...
@@ -255,10 +250,6 @@
...
@@ -255,10 +250,6 @@
background: @sider-dark-bg-color;
background: @sider-dark-bg-color;
.active-menu-style();
.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-item.ant-menu-item-selected.@{basic-menu-prefix-cls}-menu-item__level1,
.ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 {
.ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 {
color: @white;
color: @white;
...
@@ -304,10 +295,6 @@
...
@@ -304,10 +295,6 @@
overflow: hidden;
overflow: hidden;
border-right: none;
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-item.ant-menu-item-selected.@{basic-menu-prefix-cls}-menu-item__level1,
.ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 {
.ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 {
color: @primary-color;
color: @primary-color;
...
@@ -332,6 +319,7 @@
...
@@ -332,6 +319,7 @@
align-items: center;
align-items: center;
}
}
}
}
.@{basic-menu-prefix-cls}__tag {
.@{basic-menu-prefix-cls}__tag {
position: absolute;
position: absolute;
top: calc(50% - 8px);
top: calc(50% - 8px);
...
@@ -368,6 +356,20 @@
...
@@ -368,6 +356,20 @@
background: @warning-color;
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 {
.ant-menu-dark {
...
@@ -375,7 +377,6 @@
...
@@ -375,7 +377,6 @@
> ul {
> ul {
background: @sider-dark-bg-color;
background: @sider-dark-bg-color;
}
}
.active-menu-style();
.active-menu-style();
}
}
}
}
...
...
src/components/Menu/src/props.ts
浏览文件 @
cbcd9098
...
@@ -3,57 +3,47 @@ import type { PropType } from 'vue';
...
@@ -3,57 +3,47 @@ import type { PropType } from 'vue';
import
{
MenuModeEnum
,
MenuTypeEnum
}
from
'/@/enums/menuEnum'
;
import
{
MenuModeEnum
,
MenuTypeEnum
}
from
'/@/enums/menuEnum'
;
import
{
ThemeEnum
}
from
'/@/enums/appEnum'
;
import
{
ThemeEnum
}
from
'/@/enums/appEnum'
;
import
{
propTypes
}
from
'/@/utils/propTypes'
;
export
const
basicProps
=
{
export
const
basicProps
=
{
items
:
{
items
:
{
type
:
Array
as
PropType
<
Menu
[]
>
,
type
:
Array
as
PropType
<
Menu
[]
>
,
default
:
()
=>
[],
default
:
()
=>
[],
},
},
appendClass
:
{
appendClass
:
propTypes
.
bool
,
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
collapsedShowTitle
:
{
collapsedShowTitle
:
propTypes
.
bool
,
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
// 最好是4 倍数
// 最好是4 倍数
inlineIndent
:
{
inlineIndent
:
propTypes
.
number
.
def
(
20
),
type
:
Number
as
PropType
<
number
>
,
default
:
20
,
},
// 菜单组件的mode属性
// 菜单组件的mode属性
mode
:
{
mode
:
{
type
:
String
as
PropType
<
MenuModeEnum
>
,
type
:
String
as
PropType
<
MenuModeEnum
>
,
default
:
MenuModeEnum
.
INLINE
,
default
:
MenuModeEnum
.
INLINE
,
},
},
showLogo
:
{
showLogo
:
propTypes
.
bool
,
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
type
:
{
type
:
{
type
:
String
as
PropType
<
MenuTypeEnum
>
,
type
:
String
as
PropType
<
MenuTypeEnum
>
,
default
:
MenuTypeEnum
.
MIX
,
default
:
MenuTypeEnum
.
MIX
,
},
},
theme
:
{
theme
:
propTypes
.
string
.
def
(
ThemeEnum
.
DARK
),
type
:
String
as
PropType
<
string
>
,
inlineCollapsed
:
propTypes
.
bool
,
default
:
ThemeEnum
.
DARK
,
},
inlineCollapsed
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
isHorizontal
:
{
isHorizontal
:
propTypes
.
bool
,
type
:
Boolean
as
PropType
<
boolean
>
,
accordion
:
propTypes
.
bool
.
def
(
true
),
default
:
false
,
},
accordion
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
beforeClickFn
:
{
beforeClickFn
:
{
type
:
Function
as
PropType
<
(
key
:
string
)
=>
Promise
<
boolean
>>
,
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 { ComputedRef } from 'vue';
import
{
ThemeEnum
}
from
'/@/enums/appEnum'
;
//
import { ThemeEnum } from '/@/enums/appEnum';
import
{
MenuModeEnum
}
from
'/@/enums/menuEnum'
;
//
import { MenuModeEnum } from '/@/enums/menuEnum';
export
interface
MenuState
{
export
interface
MenuState
{
// 默认选中的列表
// 默认选中的列表
defaultSelectedKeys
:
string
[];
defaultSelectedKeys
:
string
[];
// 模式
// 模式
mode
:
MenuModeEnum
;
//
mode: MenuModeEnum;
// 主题
//
//
主题
theme
:
ComputedRef
<
ThemeEnum
>
|
ThemeEnum
;
//
theme: ComputedRef<ThemeEnum> | ThemeEnum;
// 缩进
// 缩进
inlineIndent
?:
number
;
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
const
SIDE_BAR_SHOW_TIT_MINI_WIDTH
=
80
;
export
enum
ContentEnum
{
export
enum
ContentEnum
{
...
...
src/layouts/default/tabs/index.less
浏览文件 @
cbcd9098
...
@@ -34,9 +34,9 @@
...
@@ -34,9 +34,9 @@
border:
1
px
solid
darken
(
@border-color-light
,
6
%
);
border:
1
px
solid
darken
(
@border-color-light
,
6
%
);
transition:
none
;
transition:
none
;
&:
not
(.
ant-tabs-tab-active
)
::
before
{
&:
not
(.
ant-tabs-tab-active
)
::
after
{
position:
absolute
;
position:
absolute
;
top
:
-1
px
;
bottom
:
-1
px
;
left:
50
%
;
left:
50
%
;
width:
100
%
;
width:
100
%
;
height:
2
px
;
height:
2
px
;
...
@@ -53,7 +53,7 @@
...
@@ -53,7 +53,7 @@
opacity:
1
;
opacity:
1
;
}
}
&:
not
(.
ant-tabs-tab-active
)
::
before
{
&:
not
(.
ant-tabs-tab-active
)
::
after
{
opacity:
1
;
opacity:
1
;
transform:
translate
(
-50
%,
0
)
scaleX
(
1
);
transform:
translate
(
-50
%,
0
)
scaleX
(
1
);
transition:
all
0.3
s
ease-in-out
;
transition:
all
0.3
s
ease-in-out
;
...
...
src/router/helper/menuHelper.ts
浏览文件 @
cbcd9098
...
@@ -42,6 +42,7 @@ export function transformMenuModule(menuModule: MenuModule): Menu {
...
@@ -42,6 +42,7 @@ export function transformMenuModule(menuModule: MenuModule): Menu {
forEach
(
menuList
,
(
m
)
=>
{
forEach
(
menuList
,
(
m
)
=>
{
!
isUrl
(
m
.
path
)
&&
joinParentPath
(
menuList
,
m
);
!
isUrl
(
m
.
path
)
&&
joinParentPath
(
menuList
,
m
);
});
});
return
menuList
[
0
];
return
menuList
[
0
];
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论