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
e0039d25
Commit
e0039d25
authored
Dec 11, 2020
by
Sendya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: router-context
parent
9bdab4c1
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
182 additions
and
152 deletions
+182
-152
index.tsx
examples/index.tsx
+30
-28
BasicLayout.tsx
src/BasicLayout.tsx
+76
-87
index.tsx
src/GlobalHeader/index.tsx
+5
-2
RouteContext.tsx
src/RouteContext.tsx
+30
-5
SiderMenu.tsx
src/SiderMenu/SiderMenu.tsx
+24
-22
index.tsx
src/TopNavHeader/index.tsx
+11
-6
typings.ts
src/typings.ts
+0
-2
index.ts
src/utils/index.ts
+6
-0
No files found.
examples/index.tsx
View file @
e0039d25
import
'ant-design-vue/dist/antd.less'
;
import
{
createApp
,
defineComponent
,
reactive
}
from
'vue'
;
import
{
createApp
,
defineComponent
,
watch
,
ref
}
from
'vue'
;
import
{
RouterLink
}
from
'./mock-router'
;
import
{
Button
,
Avatar
,
message
}
from
'ant-design-vue'
;
import
{
default
as
ProLayout
}
from
'../src/'
;
...
...
@@ -12,49 +12,54 @@ const BasicLayout = defineComponent({
name
:
'BasicLayout'
,
inheritAttrs
:
false
,
setup
(
_
,
{
attrs
})
{
const
[
menuState
]
=
useMenuState
({
const
[
state
,
RouteContextProvider
]
=
createRouteContext
({
collapsed
:
false
,
openKeys
:
[],
openKeys
:
[
'/dashboard'
,
'/form'
],
onOpenKeys
:
(
keys
:
string
[])
=>
(
state
.
openKeys
=
keys
),
selectedKeys
:
[
'/welcome'
],
});
onSelectedKeys
:
(
keys
:
string
[])
=>
(
state
.
selectedKeys
=
keys
),
const
[
routeContext
,
RouteContextProvider
]
=
createRouteContext
({
isMobile
:
false
,
menuData
:
[],
fixSiderbar
:
false
,
fixedHeader
:
false
,
menuData
:
menus
,
sideWidth
:
208
,
hasSideMenu
:
true
,
hasHeader
:
true
,
hasFooterToolbar
:
false
,
setHasFooterToolbar
:
(
has
:
boolean
)
=>
(
routeContext
.
hasFooterToolbar
=
has
),
setHasFooterToolbar
:
(
has
:
boolean
)
=>
(
state
.
hasFooterToolbar
=
has
),
});
const
cacheOpenKeys
=
ref
<
string
[]
>
([]);
watch
(
()
=>
state
.
collapsed
,
(
collapsed
:
boolean
)
=>
{
if
(
collapsed
)
{
cacheOpenKeys
.
value
=
state
.
openKeys
;
state
.
openKeys
=
[];
}
else
{
state
.
openKeys
=
cacheOpenKeys
.
value
;
}
}
);
return
()
=>
(
<
RouteContextProvider
>
<
ProLayout
{
...
attrs
}
v
-
model=
{
[
menuS
tate
.
collapsed
,
'collapsed'
]
}
v
-
model=
{
[
s
tate
.
collapsed
,
'collapsed'
]
}
title=
{
'Pro Layout'
}
layout=
{
'mix'
}
theme=
{
'light'
}
layout=
{
'side'
}
navTheme=
{
'dark'
}
i18n=
{
(
key
:
string
)
=>
key
}
isMobile=
{
fals
e
}
menuData=
{
menus
}
matchMenuKeys=
{
[]
}
isMobile=
{
state
.
isMobil
e
}
fixSiderbar=
{
state
.
fixSiderbar
}
fixedHeader=
{
state
.
fixedHeader
}
contentWidth=
{
'Fixed'
}
primaryColor=
{
'#1890ff'
}
contentStyle=
{
{
minHeight
:
'500px'
}
}
siderWidth=
{
208
}
openKeys=
{
menuState
.
openKeys
}
selectedKeys=
{
menuState
.
selectedKeys
}
{
...
{
'
onUpdate
:
openKeys
':
$event
=
>
{
$event
&&
(
menuState
.
openKeys
=
$event
);
}
,
'onUpdate:selectedKeys': $event =
>
{
$event
&&
(
menuState
.
selectedKeys
=
$event
);
}
}}
siderWidth=
{
state
.
sideWidth
}
v
-
slots=
{
{
rightContentRender
:
()
=>
(
<
div
style=
"color: #FFF;margin-right: 16px;"
>
...
...
@@ -64,11 +69,8 @@ const BasicLayout = defineComponent({
menuHeaderRender
:
()
=>
(
<
a
>
<
img
src=
"https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg"
/>
{
menuS
tate
.
collapsed
?
null
:
(<
h1
>
Pro Layout
</
h1
>)
}
{
s
tate
.
collapsed
?
null
:
(<
h1
>
Pro Layout
</
h1
>)
}
</
a
>
),
footerRender
:
()
=>
(
<
div
>
123
</
div
>
)
}
}
>
...
...
src/BasicLayout.tsx
View file @
e0039d25
...
...
@@ -8,7 +8,7 @@ import { default as SiderMenuWrapper, SiderMenuWrapperProps } from './SiderMenu'
import
{
WrapContent
}
from
'./WrapContent'
;
import
{
default
as
Header
,
HeaderViewProps
}
from
'./Header'
;
import
{
RenderVNodeType
,
WithFalse
}
from
'./typings'
;
import
{
getComponentOrSlot
}
from
'./utils'
;
import
{
getComponentOrSlot
,
PropRenderType
,
PropTypes
}
from
'./utils'
;
import
useMergedState
from
'./hooks/useMergedState'
;
import
'./BasicLayout.less'
;
...
...
@@ -141,8 +141,6 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots,
{
!
isTop
.
value
&&
(<
SiderMenuWrapper
{
...
props
}
menuHeaderRender=
{
menuHeaderRenderFunc
||
(
menuHeaderRenderSlot
&&
(()
=>
menuHeaderRenderSlot
()))
}
onSelect=
{
handleSelect
}
onOpenChange=
{
handleOpenChange
}
onCollapse=
{
handleCollapse
}
/>)
}
<
Layout
>
...
...
@@ -150,35 +148,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots,
<
WrapContent
style=
{
props
.
contentStyle
}
>
{
slots
.
default
?.()
}
</
WrapContent
>
{
footerRender
&&
footerRender
||
footerRender
!==
false
&&
(
<
GlobalFooter
links=
{
[
{
key
:
'1'
,
title
:
'Pro Layout'
,
href
:
'https://www.github.com/vueComponent/pro-layout'
,
blankTarget
:
true
,
},
{
key
:
'2'
,
title
:
'Github'
,
href
:
'https://www.github.com/vueComponent/ant-design-vue-pro'
,
blankTarget
:
true
,
},
{
key
:
'3'
,
title
:
'@Sendya'
,
href
:
'https://www.github.com/sendya/'
,
blankTarget
:
true
,
},
]
}
copyright=
{
<
a
href=
"https://github.com/vueComponent"
target=
"_blank"
>
vueComponent
</
a
>
}
/>
)
}
{
footerRender
!==
false
&&
(
footerRender
&&
footerRender
)
}
</
Layout
>
</
Layout
>
</
div
>
...
...
@@ -191,61 +161,80 @@ ProLayout.inheritAttrs = false;
ProLayout
.
displayName
=
'ProLayout'
;
ProLayout
.
emits
=
[
'update:collapsed'
,
'update:openKeys'
,
'update:selectedKeys'
];
ProLayout
.
props
=
{
prefixCls
:
{
type
:
String
,
default
:
'ant-pro'
,
},
title
:
String
,
colSize
:
String
,
isChildrenLayout
:
Boolean
,
isMobile
:
Boolean
,
fixSiderbar
:
{
type
:
Boolean
,
default
:
()
=>
false
,
},
fixedHeader
:
{
type
:
Boolean
,
default
:
()
=>
false
,
},
layout
:
String
,
openKeys
:
Array
,
selectedKeys
:
Array
,
collapsed
:
Boolean
,
menuData
:
Array
,
contentStyle
:
Object
,
theme
:
String
,
headerTheme
:
{
type
:
String
,
defualt
:
'light'
,
},
navTheme
:
{
type
:
String
,
default
:
'light'
,
},
headerRender
:
{
type
:
[
Function
,
Boolean
],
default
:
()
=>
undefined
,
},
footerRender
:
{
type
:
[
Function
,
Boolean
],
default
:
()
=>
undefined
,
},
menuRender
:
{
type
:
[
Function
,
Boolean
],
default
:
()
=>
undefined
,
},
menuHeaderRender
:
{
type
:
[
Function
,
Boolean
],
default
:
()
=>
undefined
,
},
rightContentRender
:
{
type
:
[
Function
,
Boolean
],
default
:
()
=>
undefined
,
},
rightContent
:
{
type
:
[
Function
,
Boolean
],
default
:
()
=>
undefined
,
},
prefixCls
:
PropTypes
.
string
.
def
(
'ant-pro'
),
title
:
PropTypes
.
VNodeChild
.
def
(
'Ant Design Pro'
),
logo
:
PropTypes
.
VNodeChild
,
/* 是否删除掉所有的自带界面 */
pure
:
PropTypes
.
bool
,
/* layout 的加载态 */
loading
:
PropTypes
.
bool
,
/* 用于生成菜单和面包屑 请从 RouterContext 注入 */
// menuData: PropTypes.array,
// location: PropTypes.string,
// Custom render
menuHeaderRender
:
PropRenderType
,
menuFooterRender
:
PropRenderType
,
menuExtraRender
:
PropRenderType
,
/* 自定义头的 render 方法 (props: BasicLayoutProps) => VNode */
headerRender
:
PropRenderType
,
/* 自定义头标题的方法,mix 模式下生效 (props: BasicLayoutProps) => VNode */
headerTitleRender
:
PropRenderType
,
/* 自定义头内容的方法 (props: BasicLayoutProps) => VNode */
headerContentRender
:
PropRenderType
,
/* 自定义头右部的 render 方法 (props: HeaderViewProps) => VNode */
rightContentRender
:
PropRenderType
,
/* 自定义 collapsed button 的方法 (collapsed: boolean) => VNode */
collapsedButtonRender
:
PropRenderType
,
/* 自定义页脚的 render 方法 (props: BasicLayoutProps) => VNode */
footerRender
:
PropRenderType
,
/* 自定义页面标题的显示方法 (props: BasicLayoutProps) => VNode */
pageTitleRender
:
PropRenderType
,
/* 自定义菜单的 render 方法 (props: HeaderViewProps) => VNode */
menuRender
:
PropRenderType
,
/* 自定义菜单项的 render 方法 */
menuItemRender
:
PropRenderType
,
/* 自定义拥有子菜单菜单项的 render 方法 */
subMenuItemRender
:
PropRenderType
,
/* 自定义面包屑的数据 */
breadcrumbRender
:
PropRenderType
,
// Event
onMenuHeaderClick
:
PropTypes
.
func
,
onTopMixMenuHeaderClick
:
PropTypes
.
func
,
// settings
contentStyle
:
PropTypes
.
style
,
layout
:
PropTypes
.
string
.
def
(
'side'
),
contentWidth
:
PropTypes
.
string
.
def
(
'Fluid'
),
/* 导航的主题,side 和 mix 模式下是左侧菜单的主题,top 模式下是顶部菜单 */
navTheme
:
PropTypes
.
string
.
def
(
'dark'
),
/* 顶部导航的主题,mix 模式生效 */
headerTheme
:
PropTypes
.
string
.
def
(
'dark'
),
/* 是否固定导航 */
fixSiderbar
:
PropTypes
.
bool
,
/* 是否固定 header 到顶部 */
fixedHeader
:
PropTypes
.
bool
,
/* 触发响应式布局的断点 https://ant.design/components/grid-cn/#Col */
breakpoint
:
PropTypes
.
string
.
def
(
'lg'
),
/* 关于 menu 的配置,暂时只有 locale,locale 可以关闭 menu 的自带的全球化 */
menu
:
PropTypes
.
object
,
/* 传递到 antd menu 组件的 props */
menuProps
:
PropTypes
.
object
,
/* 使用 IconFont 的图标配置 */
iconfontUrl
:
PropTypes
.
string
,
/* 当前 layout 的语言设置 */
locale
:
PropTypes
.
func
.
def
((
key
:
string
)
=>
key
),
// settings
/* 侧边菜单宽度 */
siderWidth
:
PropTypes
.
number
.
def
(
208
),
/* 控制菜单的收起和展开 */
collapsed
:
PropTypes
.
bool
,
/* 菜单的折叠收起事件 (collapsed: boolean) => void */
onCollapse
:
PropTypes
.
func
,
// onPageChange // 请使用 vue-router 监听
/* 禁止自动切换到移动页面 */
disableMobile
:
PropTypes
.
bool
,
}
as
any
;
export
default
withInstall
(
ProLayout
);
src/GlobalHeader/index.tsx
View file @
e0039d25
...
...
@@ -6,6 +6,7 @@ import { TopNavHeader } from '../TopNavHeader';
import
{
clearMenuItem
}
from
'../utils'
;
import
type
{
HeaderViewProps
}
from
'../Header'
;
import
'./index.less'
;
import
{
useProProvider
}
from
'../ProProvider'
;
export
interface
GlobalHeaderProps
extends
Partial
<
PureSettings
>
{
collapsed
?:
boolean
;
...
...
@@ -52,8 +53,10 @@ export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderM
headerTheme
=
'dark'
,
splitMenus
,
menuData
,
prefixCls
,
prefixCls
:
customPrefixCls
,
}
=
props
;
const
{
getPrefixCls
}
=
useProProvider
();
const
prefixCls
=
customPrefixCls
||
getPrefixCls
();
const
baseClassName
=
computed
(()
=>
`
${
prefixCls
}
-global-header`
);
const
className
=
computed
(()
=>
{
return
{
...
...
@@ -89,7 +92,7 @@ export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderM
{
isMobile
&&
renderLogo
(
menuHeaderRender
,
logoDom
)
}
{
isMobile
&&
collapsedButtonRender
&&
(
<
span
class=
{
`${baseClassName.value}-collapsed-button`
}
class=
{
`${baseClassName.value}-collapsed-button`
}
onClick=
{
()
=>
{
if
(
onCollapse
)
{
onCollapse
(
!
collapsed
);
...
...
src/RouteContext.tsx
View file @
e0039d25
import
{
InjectionKey
}
from
'vue'
;
import
{
InjectionKey
,
VNodeChild
}
from
'vue'
;
import
{
createContext
,
useContext
}
from
'./hooks/context'
;
import
{
MenuDataItem
}
from
'./typings'
;
import
{
PureSettings
}
from
'./defaultSettings'
;
export
interface
Route
{
path
:
string
;
breadcrumbName
:
string
;
children
?:
Omit
<
Route
,
'children'
>
[];
}
export
interface
BreadcrumbProps
{
prefixCls
?:
string
;
routes
?:
Route
[];
params
?:
any
;
separator
?:
VNodeChild
;
itemRender
?:
(
route
:
Route
,
params
:
any
,
routes
:
Array
<
Route
>
,
paths
:
Array
<
string
>
)
=>
VNodeChild
;
}
export
type
BreadcrumbListReturn
=
Pick
<
BreadcrumbProps
,
Extract
<
keyof
BreadcrumbProps
,
'routes'
|
'itemRender'
>>
;
export
interface
MenuState
{
selectedKeys
?:
string
[];
openKeys
?:
string
[];
onSelectedKeys
:
(
key
:
string
[])
=>
void
;
onOpenKeys
:
(
key
:
string
[])
=>
void
;
}
export
interface
RouteContextProps
extends
Partial
<
PureSettings
>
{
breadcrumb
?:
any
;
menuData
?:
any
[];
export
interface
RouteContextProps
extends
Partial
<
PureSettings
>
,
MenuState
{
breadcrumb
?:
BreadcrumbListReturn
;
menuData
?:
MenuDataItem
[];
isMobile
?:
boolean
;
prefixCls
?:
string
;
collapsed
?:
boolean
;
...
...
@@ -14,6 +36,8 @@ export interface RouteContextProps extends Partial<PureSettings> {
hasFooterToolbar
?:
boolean
;
hasFooter
?:
boolean
;
setHasFooterToolbar
?:
(
bool
:
boolean
)
=>
void
;
/* 附加属性 */
[
key
:
string
]:
any
;
}
const
routeContextInjectKey
:
InjectionKey
<
RouteContextProps
>
=
Symbol
();
...
...
@@ -21,4 +45,5 @@ const routeContextInjectKey: InjectionKey<RouteContextProps> = Symbol();
export
const
createRouteContext
=
(
context
:
RouteContextProps
)
=>
createContext
<
RouteContextProps
>
(
context
,
routeContextInjectKey
);
export
const
useRouteContext
=
()
=>
useContext
<
RouteContextProps
>
(
routeContextInjectKey
);
export
const
useRouteContext
=
()
=>
useContext
<
RouteContextProps
>
(
routeContextInjectKey
);
src/SiderMenu/SiderMenu.tsx
View file @
e0039d25
...
...
@@ -9,6 +9,7 @@ import { SiderProps } from './typings';
import
{
MenuUnfoldOutlined
,
MenuFoldOutlined
}
from
'@ant-design/icons-vue'
;
import
{
useProProvider
}
from
'../ProProvider'
;
import
'./index.less'
;
import
{
useRouteContext
}
from
'../RouteContext'
;
const
{
Sider
}
=
Layout
;
...
...
@@ -34,8 +35,8 @@ export interface SiderMenuProps
onMenuHeaderClick
?:
(
e
:
MouseEvent
)
=>
void
;
fixed
?:
boolean
;
hide
?:
boolean
;
onOpenChange
?:
(
openKeys
:
WithFalse
<
string
[]
>
)
=>
void
;
onSelect
?:
(
selectedKeys
:
WithFalse
<
string
[]
>
)
=>
void
;
//
onOpenChange?: (openKeys: WithFalse<string[]>) => void;
//
onSelect?: (selectedKeys: WithFalse<string[]>) => void;
}
export
const
defaultRenderLogo
=
(
logo
:
RenderVNodeType
):
RenderVNodeType
=>
{
...
...
@@ -84,12 +85,10 @@ export const defaultRenderCollapsedButton = (collapsed?: boolean): RenderVNodeTy
const
SiderMenu
:
FunctionalComponent
<
SiderMenuProps
>
=
(
props
:
SiderMenuProps
)
=>
{
const
{
t
heme
,
menuData
,
navT
heme
,
//
menuData,
collapsed
,
siderWidth
,
onOpenChange
,
onSelect
,
onCollapse
,
breakpoint
,
collapsedWidth
=
48
,
...
...
@@ -99,42 +98,45 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
collapsedButtonRender
=
defaultRenderCollapsedButton
,
}
=
props
;
const
{
getPrefixCls
}
=
useProProvider
();
const
context
=
useRouteContext
();
const
baseClassName
=
getPrefixCls
(
'sider'
);
// const isMix = computed(() => props.layout === 'mix');
const
fixed
=
computed
(()
=>
props
.
fixed
);
// const fixed = computed(() => context.fixSiderbar
);
// const runtimeTheme = computed(() => (props.layout === 'mix' && 'light') || 'dark');
const
runtimeSideWidth
=
computed
(()
=>
props
.
collapsed
?
props
.
collapsedWidth
:
props
.
siderWidth
,
);
const
classNames
=
ref
({
[
baseClassName
]:
true
,
[
`
${
baseClassName
}
-
${
theme
}
`
]:
true
,
[
`
${
baseClassName
}
-
${
props
.
layout
}
`
]:
true
,
[
`
${
baseClassName
}
-fixed`
]:
fixed
,
const
classNames
=
computed
(()
=>
{
return
{
[
baseClassName
]:
true
,
[
`
${
baseClassName
}
-
${
navTheme
}
`
]:
true
,
[
`
${
baseClassName
}
-
${
props
.
layout
}
`
]:
true
,
[
`
${
baseClassName
}
-fixed`
]:
context
.
fixSiderbar
,
}
});
// call menuHeaderRender
const
headerDom
=
defaultRenderLogoAndTitle
(
props
);
const
extraDom
=
menuExtraRender
&&
menuExtraRender
(
props
);
const
defaultMenuDom
=
(
<
BaseMenu
menuData=
{
menuData
}
theme=
{
props
.
theme
===
'realDark'
?
'dark'
:
props
.
theme
}
theme=
{
props
.
navTheme
===
'realDark'
?
'dark'
:
props
.
navTheme
}
mode=
"inline"
menuData=
{
context
.
menuData
}
collapsed=
{
props
.
collapsed
}
openKeys=
{
props
.
openKeys
}
selectedKeys=
{
props
.
selectedKeys
}
openKeys=
{
context
.
openKeys
}
selectedKeys=
{
context
.
selectedKeys
}
style=
{
{
width
:
'100%'
,
}
}
class=
{
`${baseClassName}-menu`
}
{
...
{
'
onUpdate
:
openKeys
':
(
$event
:
any
)
=
>
{
onOpenChange
&&
onOpenChange
(
$event
);
'
onUpdate
:
openKeys
':
(
$event
:
string
[]
)
=
>
{
context
.
onOpenKeys
(
$event
);
}
,
'onUpdate:selectedKeys': ($event:
any
) =
>
{
onSelect
&&
onSelect
(
$event
);
'onUpdate:selectedKeys': ($event:
string[]
) =
>
{
context
.
onSelectedKeys
(
$event
);
}
,
}}
/
>
...
...
@@ -142,7 +144,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
return (
<>
{
fixed
.
value
&&
(
{
context
.
fixSiderbar
&&
(
<
div
style=
{
{
width
:
`${runtimeSideWidth.value}px`
,
...
...
@@ -174,7 +176,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
<
Menu
class=
{
`${baseClassName}-link-menu`
}
inlineIndent=
{
16
}
theme=
{
theme
}
theme=
{
navTheme
as
'light'
|
'dark'
}
selectedKeys=
{
[]
}
openKeys=
{
[]
}
mode=
"inline"
...
...
src/TopNavHeader/index.tsx
View file @
e0039d25
...
...
@@ -9,6 +9,7 @@ import { GlobalHeaderProps } from '../GlobalHeader';
import
{
default
as
ResizeObserver
}
from
'ant-design-vue/es/vc-resize-observer'
;
import
'./index.less'
;
import
{
useRouteContext
}
from
"../RouteContext"
;
export
type
TopNavHeaderProps
=
SiderMenuProps
&
GlobalHeaderProps
&
PrivateSiderMenuProps
&
{};
...
...
@@ -52,10 +53,9 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = (props, { em
contentWidth
,
rightContentRender
,
layout
,
onOpenChange
,
onSelect
,
...
restProps
}
=
props
;
const
context
=
useRouteContext
();
const
prefixCls
=
`
${
propPrefixCls
||
'ant-pro'
}
-top-nav-header`
;
const
headerDom
=
defaultRenderLogoAndTitle
(
{
...
props
,
collapsed
:
false
},
...
...
@@ -79,14 +79,19 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = (props, { em
)
}
<
div
style=
{
{
flex
:
1
}
}
class=
{
`${prefixCls}-menu`
}
>
<
BaseMenu
{
...
restProps
}
theme=
{
props
.
theme
===
'realDark'
?
'dark'
:
props
.
theme
}
mode=
{
props
.
mode
}
collapsed=
{
props
.
collapsed
}
menuData=
{
context
.
menuData
}
openKeys=
{
context
.
openKeys
}
selectedKeys=
{
context
.
selectedKeys
}
class=
{
{
'top-nav-menu'
:
props
.
mode
===
'horizontal'
}
}
{
...
{
'
onUpdate
:
openKeys
':
(
$event
:
any
)
=
>
{
onOpenChange
&&
onOpenChange
(
$event
);
'
onUpdate
:
openKeys
':
(
$event
:
string
[]
)
=
>
{
context
.
onOpenKeys
(
$event
);
}
,
'onUpdate:selectedKeys': ($event: any) =
>
{
onSelect
&&
onSelect
(
$event
);
context
.
onSelectedKeys
(
$event
);
}
,
}}
/
>
...
...
src/typings.ts
View file @
e0039d25
...
...
@@ -52,11 +52,9 @@ export interface MenuDataItem {
/**
* @name 用于标定选中的值,默认是 path
*/
key
?:
string
|
symbol
;
path
:
string
;
name
?:
string
|
symbol
;
meta
?:
MetaRecord
;
hidden
?:
boolean
;
/**
* @name 子菜单
*/
...
...
src/utils/index.ts
View file @
e0039d25
import
{
Slots
,
VNodeChild
}
from
'vue'
;
import
{
MenuDataItem
}
from
'../typings'
;
export
{
getComponent
}
from
'ant-design-vue/es/_util/props-util'
;
export
{
default
as
PropTypes
}
from
'ant-design-vue/es/_util/vue-types'
;
export
{
default
as
isUrl
}
from
'./isUrl'
;
export
{
default
as
isImg
}
from
'./isImg'
;
...
...
@@ -48,6 +49,11 @@ export function clearMenuItem(menusData: MenuDataItem[]): MenuDataItem[] {
.
filter
(
item
=>
item
)
as
MenuDataItem
[];
}
export
const
PropRenderType
=
{
type
:
[
Function
,
Boolean
],
default
:
()
=>
undefined
,
};
export
interface
Attrs
{
[
key
:
string
]:
string
;
}
...
...
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