Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pro-layout
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
packages
pro-layout
Commits
1c2a611c
Unverified
Commit
1c2a611c
authored
May 19, 2021
by
Sendya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add menuItemRender, subMenuItemRender
parent
b70b15bd
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
146 additions
and
27 deletions
+146
-27
child-form.tsx
examples/demo/child/child-form.tsx
+15
-0
child-page.tsx
examples/demo/child/child-page.tsx
+7
-3
child-table.tsx
examples/demo/child/child-table.tsx
+43
-0
form.tsx
examples/demo/form.tsx
+1
-1
index.tsx
examples/index.tsx
+31
-8
index.tsx
src/PageContainer/index.tsx
+1
-1
BaseMenu.tsx
src/SiderMenu/BaseMenu.tsx
+43
-12
SiderMenu.tsx
src/SiderMenu/SiderMenu.tsx
+2
-0
index.tsx
src/SiderMenu/index.tsx
+3
-2
No files found.
examples/demo/child/child-form.tsx
0 → 100644
View file @
1c2a611c
import
{
defineComponent
}
from
'vue'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
PageContainer
,
Route
}
from
'../../../src'
;
export
default
defineComponent
({
setup
()
{
const
route
=
useRoute
();
return
()
=>
(
<
div
>
<
h1
>
Child Form:
{
route
.
meta
.
title
}
</
h1
>
<
pre
>
{
JSON
.
stringify
(
route
.
meta
,
null
,
4
)
}
</
pre
>
</
div
>
);
},
});
examples/demo/child/child-page.tsx
View file @
1c2a611c
import
{
defineComponent
}
from
'vue'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
i18n
}
from
'../../index'
;
import
{
PageContainer
}
from
'../../../src'
;
export
default
defineComponent
({
setup
()
{
const
route
=
useRoute
();
return
()
=>
(
<
div
>
<
h1
>
Child
</
h1
>
<
PageContainer
title=
{
i18n
(
`${route.meta.title}`
)
}
>
<
router
-
view
/>
</
div
>
</
PageContainer
>
);
},
});
examples/demo/child/child-table.tsx
0 → 100644
View file @
1c2a611c
import
{
defineComponent
}
from
'vue'
;
import
{
useRoute
,
useRouter
}
from
'vue-router'
;
import
{
Table
,
Button
}
from
'ant-design-vue'
;
import
{
PlusOutlined
}
from
'@ant-design/icons-vue'
;
export
default
defineComponent
({
setup
()
{
const
router
=
useRouter
();
const
route
=
useRoute
();
const
columns
=
[
{
dataIndex
:
'key'
,
title
:
'#'
},
{
dataIndex
:
'title'
,
title
:
'标题'
},
{
dataIndex
:
'content'
,
title
:
'内容'
},
{
dataIndex
:
'action'
,
title
:
'操作'
,
customRender
:
({
record
})
=>
{
return
(
<>
<
a
>
编辑
</
a
>
<
a
>
删除
</
a
>
</>
);
},
},
];
return
()
=>
(
<
div
>
<
h1
>
Child Table:
{
route
.
meta
.
title
}
</
h1
>
<
Button
style=
{
{
marginBottom
:
'12px'
}
}
onClick=
{
()
=>
{
router
.
push
({
path
:
'/form/child/page2'
});
}
}
>
<
PlusOutlined
/>
新增
</
Button
>
<
Table
columns=
{
columns
}
/>
</
div
>
);
},
});
examples/demo/form.tsx
View file @
1c2a611c
...
...
@@ -7,7 +7,7 @@ export default defineComponent({
const
route
=
useRoute
();
return
()
=>
(
<
PageContainer
title=
{
route
.
meta
.
title
}
title=
{
route
.
meta
?
.
title
}
breadcrumb=
{
{
routes
:
[{
path
:
'/'
,
breadcrumbName
:
'home'
}]
as
Route
[],
}
}
...
...
examples/index.tsx
View file @
1c2a611c
import
'ant-design-vue/dist/antd.less'
;
import
{
createApp
,
defineComponent
,
watch
,
ref
,
watchEffect
,
onMounted
,
computed
}
from
'vue'
;
import
{
createRouter
,
createWebHashHistory
,
useRoute
,
useRouter
,
RouterLink
}
from
'vue-router'
;
import
{
Avatar
,
Button
,
Space
,
Select
,
Switch
}
from
'ant-design-vue'
;
import
{
UserOutlined
}
from
'@ant-design/icons-vue'
;
import
{
Avatar
,
Button
,
Space
,
Select
,
Switch
,
Menu
}
from
'ant-design-vue'
;
import
{
UserOutlined
,
SmileOutlined
}
from
'@ant-design/icons-vue'
;
import
{
default
as
ProLayout
,
FooterToolbar
,
WaterMark
,
getMenuData
,
Route
}
from
'../src/'
;
import
{
globalState
as
state
}
from
'./state'
;
import
'./demo.less'
;
...
...
@@ -14,6 +14,8 @@ import Page1 from './demo/page1';
import
Welcome
from
'./demo/welcome'
;
import
FormPage
from
'./demo/form'
;
import
ChildPage
from
'./demo/child/child-page'
;
import
ChildTable
from
'./demo/child/child-table'
;
import
ChildForm
from
'./demo/child/child-form'
;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const
noop
=
()
=>
{};
...
...
@@ -46,6 +48,9 @@ const BasicLayout = defineComponent({
matched
.
shift
();
state
.
selectedKeys
=
matched
;
};
const
updateOpenKeys
=
()
=>
{
state
.
openKeys
=
route
.
matched
.
concat
().
map
(
item
=>
item
.
path
);
};
onMounted
(()
=>
{
// if sider collapsed, set openKeys is null.
...
...
@@ -65,6 +70,7 @@ const BasicLayout = defineComponent({
// watch route
watchEffect
(()
=>
{
updateSelectedMenu
();
updateOpenKeys
();
});
});
...
...
@@ -108,6 +114,23 @@ const BasicLayout = defineComponent({
{
state
.
collapsed
&&
state
.
layout
!==
'mix'
?
null
:
<
h1
>
Pro Preview
</
h1
>
}
</
a
>
)
}
menuItemRender=
{
item
=>
{
return
(
<
Menu
.
Item
inlineIndent=
{
24
}
key=
{
item
.
path
}
>
<
router
-
link
to=
{
{
...
item
.
meta
,
path
:
item
.
path
}
}
>
<
SmileOutlined
/>
<
span
class=
"custom-menu-item"
>
{
i18n
(
`${item.meta.title}`
)
}
</
span
>
</
router
-
link
>
</
Menu
.
Item
>
);
}
}
subMenuItemRender=
{
(
item
,
children
)
=>
{
return
(
<
Menu
.
SubMenu
title=
{
<
span
>
{
i18n
(
`${item.meta.title}`
)
}
</
span
>
}
key=
{
item
.
path
}
>
{
children
}
</
Menu
.
SubMenu
>
);
}
}
breadcrumbRender=
{
({
route
:
r
,
routes
,
paths
})
=>
routes
.
indexOf
(
r
)
===
routes
.
length
-
1
?
(
<
span
>
{
i18n
(
r
.
breadcrumbName
)
}
</
span
>
...
...
@@ -258,15 +281,15 @@ const routes = [
children
:
[
{
path
:
'/form/child/page1'
,
name
:
'child-page1-
form
'
,
meta
:
{
title
:
'Page1 Child'
},
component
:
FormPag
e
,
name
:
'child-page1-
table
'
,
meta
:
{
title
:
'Page1 Child
Table
'
},
component
:
ChildTabl
e
,
},
{
path
:
'/form/child/page2'
,
name
:
'child-page
2
-form'
,
meta
:
{
title
:
'Page2 Child'
},
component
:
FormPage
,
name
:
'child-page
1
-form'
,
meta
:
{
title
:
'Page2 Child
Form
'
},
component
:
ChildForm
,
},
],
},
...
...
src/PageContainer/index.tsx
View file @
1c2a611c
...
...
@@ -245,7 +245,7 @@ const PageContainer: FunctionalComponent<PageContainerProps> = (props, { slots }
headerDom
)
}
<
GridContent
>
{
loading
?
<
Spin
/>
:
content
}
</
GridContent
>
{
foote
r
&&
<
FooterToolbar
>
{
footer
}
</
FooterToolbar
>
}
{
value
.
hasFooterToolba
r
&&
<
FooterToolbar
>
{
footer
}
</
FooterToolbar
>
}
</
div
>
);
};
...
...
src/SiderMenu/BaseMenu.tsx
View file @
1c2a611c
...
...
@@ -15,7 +15,7 @@ import Menu from 'ant-design-vue/es/menu';
import
defaultSettings
,
{
PureSettings
}
from
'../defaultSettings'
;
import
{
isImg
,
isUrl
}
from
'../utils'
;
import
{
MenuMode
,
SelectInfo
,
OpenEventHandler
}
from
'./typings'
;
import
{
MenuDataItem
,
MenuTheme
,
FormatMessage
,
WithFalse
}
from
'../typings'
;
import
{
MenuDataItem
,
MenuTheme
,
FormatMessage
,
CustomRender
,
WithFalse
}
from
'../typings'
;
import
{
PrivateSiderMenuProps
}
from
'./SiderMenu'
;
import
'./index.less'
;
...
...
@@ -26,7 +26,15 @@ export function useRootSubmenuKeys(menus: MenuDataItem[]): ComputedRef<string[]>
}
// ts typo
export
interface
BaseMenuProps
extends
Partial
<
PureSettings
>
,
PrivateSiderMenuProps
{
interface
CustomMenuRender
{
menuItemRender
:
WithFalse
<
(
item
:
MenuDataItem
)
=>
CustomRender
>
;
subMenuItemRender
:
WithFalse
<
(
item
:
MenuDataItem
,
children
?:
CustomRender
[])
=>
CustomRender
>
;
}
export
interface
BaseMenuProps
extends
Partial
<
PureSettings
>
,
PrivateSiderMenuProps
,
CustomMenuRender
{
menuProps
?:
Record
<
string
,
any
>
;
prefixCls
?:
string
;
collapsed
?:
boolean
;
splitMenus
?:
boolean
;
...
...
@@ -78,6 +86,18 @@ export const baseMenuProps = {
type
:
Array
as
PropType
<
WithFalse
<
string
[]
>>
,
default
:
undefined
,
},
menuProps
:
{
type
:
Object
as
PropType
<
BaseMenuProps
[
'menuProps'
]
>
,
default
:
()
=>
null
,
},
menuItemRender
:
{
type
:
[
Function
,
Boolean
]
as
PropType
<
BaseMenuProps
[
'menuItemRender'
]
>
,
default
:
()
=>
false
,
},
subMenuItemRender
:
{
type
:
[
Function
,
Boolean
]
as
PropType
<
BaseMenuProps
[
'subMenuItemRender'
]
>
,
default
:
()
=>
false
,
},
};
const
IconFont
=
createFromIconfontCN
({
...
...
@@ -123,12 +143,19 @@ class MenuUtil {
return
menusData
.
map
(
item
=>
this
.
getSubMenuOrItem
(
item
,
isChildren
)).
filter
(
item
=>
item
);
};
getSubMenuOrItem
=
(
item
:
MenuDataItem
,
isChildren
:
boolean
)
=>
{
getSubMenuOrItem
=
(
item
:
MenuDataItem
,
isChildren
:
boolean
)
:
VNode
=>
{
if
(
Array
.
isArray
(
item
.
children
)
&&
item
.
children
.
length
>
0
&&
!
item
?.
meta
?.
hideInMenu
&&
!
item
?.
meta
?.
hideChildrenInMenu
)
{
if
(
this
.
props
.
subMenuItemRender
)
{
return
this
.
props
.
subMenuItemRender
(
item
,
this
.
getNavMenuItems
(
item
.
children
,
true
),
)
as
VNode
;
}
const
{
prefixCls
,
i18n
}
=
this
.
props
;
const
menuTitle
=
(
i18n
&&
i18n
(
item
.
meta
?.
title
))
||
item
.
meta
?.
title
;
const
defaultTitle
=
item
.
meta
?.
icon
?
(
...
...
@@ -139,6 +166,7 @@ class MenuUtil {
)
:
(
<
span
class=
{
`${prefixCls}-menu-item`
}
>
{
menuTitle
}
</
span
>
);
const
MenuComponent
=
item
.
meta
?.
type
===
'group'
?
Menu
.
ItemGroup
:
Menu
.
SubMenu
;
return
(
<
MenuComponent
title=
{
defaultTitle
}
key=
{
item
.
path
}
>
...
...
@@ -148,14 +176,16 @@ class MenuUtil {
}
return
(
<
Menu
.
Item
inlineIndent=
{
24
}
disabled=
{
item
.
meta
?.
disabled
}
key=
{
item
.
path
}
// onClick={}
>
{
this
.
getMenuItem
(
item
,
isChildren
)
}
</
Menu
.
Item
>
((
this
.
props
.
menuItemRender
&&
this
.
props
.
menuItemRender
(
item
))
as
VNode
)
||
(
<
Menu
.
Item
inlineIndent=
{
24
}
disabled=
{
item
.
meta
?.
disabled
}
key=
{
item
.
path
}
// onClick={}
>
{
this
.
getMenuItem
(
item
,
isChildren
)
}
</
Menu
.
Item
>
)
);
};
...
...
@@ -165,7 +195,7 @@ class MenuUtil {
const
hasUrl
=
isUrl
(
item
.
path
);
const
CustomTag
:
any
=
resolveComponent
((
target
&&
'a'
)
||
'router-link'
);
const
props
=
{
to
:
{
name
:
item
.
name
}
};
const
attrs
=
hasUrl
||
target
?
{
href
:
item
.
path
,
target
:
target
}
:
{};
const
attrs
=
hasUrl
||
target
?
{
...
item
.
meta
,
href
:
item
.
path
,
target
:
target
}
:
{};
const
{
prefixCls
,
i18n
}
=
this
.
props
;
const
menuTitle
=
(
i18n
&&
i18n
(
item
.
meta
?.
title
))
||
item
.
meta
?.
title
;
...
...
@@ -227,6 +257,7 @@ export default defineComponent({
selectedKeys=
{
props
.
selectedKeys
||
[]
}
onOpenChange=
{
handleOpenChange
}
onSelect=
{
handleSelect
}
{
...
props
.
menuProps
}
>
{
menuUtil
.
getNavMenuItems
(
props
.
menuData
,
false
)
}
</
Menu
>
...
...
src/SiderMenu/SiderMenu.tsx
View file @
1c2a611c
...
...
@@ -137,6 +137,8 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
collapsed=
{
props
.
collapsed
}
openKeys=
{
context
.
openKeys
}
selectedKeys=
{
context
.
selectedKeys
}
menuItemRender=
{
props
.
menuItemRender
}
subMenuItemRender=
{
props
.
subMenuItemRender
}
style=
{
{
width
:
'100%'
,
}
}
...
...
src/SiderMenu/index.tsx
View file @
1c2a611c
...
...
@@ -7,7 +7,7 @@ import SiderMenu, { SiderMenuProps, PrivateSiderMenuProps } from './SiderMenu';
export
type
SiderMenuWrapperProps
=
SiderMenuProps
&
Partial
<
PrivateSiderMenuProps
>
;
const
SiderMenuWrapper
:
FunctionalComponent
<
SiderMenuWrapperProps
>
=
props
=>
{
const
SiderMenuWrapper
:
FunctionalComponent
<
SiderMenuWrapperProps
>
=
(
props
,
{
attrs
})
=>
{
return
props
.
isMobile
?
(
<
Drawer
visible=
{
!
props
.
collapsed
}
...
...
@@ -22,13 +22,14 @@ const SiderMenuWrapper: FunctionalComponent<SiderMenuWrapperProps> = props => {
bodyStyle=
{
{
height
:
'100vh'
,
padding
:
0
,
display
:
'flex'
,
flexDirection
:
'row'
}
}
>
<
SiderMenu
{
...
attrs
}
{
...
props
}
collapsed=
{
props
.
isMobile
?
false
:
props
.
collapsed
}
splitMenus=
{
false
}
/>
</
Drawer
>
)
:
(
<
SiderMenu
{
...
props
}
/>
<
SiderMenu
{
...
attrs
}
{
...
props
}
/>
);
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment