You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.8 KiB
137 lines
3.8 KiB
<script type="text/jsx">
|
|
const MenuItemContent = {
|
|
functional: true,
|
|
|
|
props: {icon: String, title: String, useTitleAsIcon: Boolean},
|
|
|
|
render(h, context) {
|
|
const {icon, title, useTitleAsIcon} = context.props
|
|
|
|
const iconComponent =
|
|
useTitleAsIcon
|
|
? <em class="icon" style="font-style: normal">{title[0]}</em>
|
|
: icon
|
|
? <v-icon icon={icon}/>
|
|
: <span class="icon" style="display: none"/>
|
|
|
|
const vnodes = [iconComponent]
|
|
|
|
title && vnodes.push(<span slot="title" class="menu-item-content">{title}</span>)
|
|
|
|
return vnodes
|
|
}
|
|
}
|
|
|
|
//根据showIconMaxDepth、depth判断是否需要限制图标的显示
|
|
function getIcon({icon, showIconMaxDepth, depth}) {
|
|
if (!showIconMaxDepth || showIconMaxDepth < 0) {
|
|
return icon
|
|
}
|
|
return showIconMaxDepth < depth ? undefined : icon
|
|
}
|
|
|
|
//获取不需要嵌套展示的菜单
|
|
function getOnlyChild(menu) {
|
|
const {children = [], meta: {alwaysShow} = {}} = menu
|
|
|
|
if (!children.length) return {...menu, children: undefined}
|
|
|
|
if (children.length === 1) return alwaysShow ? null : getOnlyChild(children[0])
|
|
|
|
return null
|
|
}
|
|
|
|
function renderSingleMenu(h, {index, icon, title, collapse, depth}) {
|
|
const useTitleAsIcon = depth === 1 && collapse && !!!icon && !!title
|
|
return (
|
|
<el-menu-item key={index} index={index}>
|
|
<MenuItemContent icon={icon} title={title} useTitleAsIcon={useTitleAsIcon}/>
|
|
</el-menu-item>
|
|
)
|
|
}
|
|
|
|
function renderSubMenu(h, {index, icon, title, children, collapse, depth}) {
|
|
const useTitleAsIcon = depth === 1 && collapse && !!!icon && !!title
|
|
return (
|
|
<el-submenu key={index} index={index} popper-append-to-body>
|
|
<MenuItemContent slot="title" icon={icon} title={title} useTitleAsIcon={useTitleAsIcon}/>
|
|
{children}
|
|
</el-submenu>
|
|
)
|
|
}
|
|
|
|
function renderChildrenWithParentMenu(h, {icon, title, children}) {
|
|
return [
|
|
<div class="popover-menu__title el-menu-item">
|
|
<MenuItemContent icon={icon} title={title}/>
|
|
</div>,
|
|
<div class="el-menu el-menu--inline">{children}</div>
|
|
]
|
|
}
|
|
|
|
function renderMenu(h, {menu, showParent, collapse, showIconMaxDepth, depth = 1}) {
|
|
const onlyOneChild = getOnlyChild(menu)
|
|
|
|
const showSingle = onlyOneChild && !onlyOneChild.children
|
|
|
|
if (showSingle) {
|
|
const {fullPath, meta: {icon, title}} = onlyOneChild
|
|
return renderSingleMenu(h, {
|
|
index: fullPath,
|
|
icon: getIcon({icon, showIconMaxDepth, depth}),
|
|
title,
|
|
collapse,
|
|
depth
|
|
})
|
|
}
|
|
|
|
const {icon, title} = menu.meta
|
|
|
|
let children = menu.children.map(child => renderMenu(h, {
|
|
menu: child,
|
|
showParent,
|
|
collapse,
|
|
showIconMaxDepth,
|
|
depth: depth + 1
|
|
}))
|
|
|
|
//这里弹出菜单如果包裹了<el-scrollbar>,则在触发mouseleave时,不会触发父菜单的mouseleave事件
|
|
if (collapse) {
|
|
//弹出菜单显示父级信息
|
|
if (showParent) {
|
|
children = renderChildrenWithParentMenu(h, {icon, title, children})
|
|
}
|
|
}
|
|
|
|
return renderSubMenu(h, {
|
|
index: menu.fullPath,
|
|
icon: getIcon({icon, showIconMaxDepth, depth}),
|
|
title,
|
|
children,
|
|
collapse,
|
|
depth
|
|
})
|
|
}
|
|
|
|
export default {
|
|
functional: true,
|
|
|
|
props: {
|
|
//菜单对象,即路由配置项
|
|
menu: Object,
|
|
|
|
//折叠时的展开菜单是否显示父级
|
|
showParent: Boolean,
|
|
|
|
//是否为折叠状态
|
|
collapse: Boolean,
|
|
|
|
//能够显示图标的最大深度,不传 或 <0 则不作限制
|
|
showIconMaxDepth: Number
|
|
},
|
|
|
|
render(h, context) {
|
|
return renderMenu(h, context.props)
|
|
}
|
|
}
|
|
</script>
|
|
|