|
|
|
@ -2,93 +2,85 @@ |
|
|
|
import path from 'path' |
|
|
|
import path from 'path' |
|
|
|
import SidebarItemContent from './SidebarItemContent' |
|
|
|
import SidebarItemContent from './SidebarItemContent' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function resolvePath(basePath, routePath = '') { |
|
|
|
|
|
|
|
const indexOf = basePath.indexOf(routePath) |
|
|
|
|
|
|
|
const samePath = basePath.length === indexOf + routePath.length |
|
|
|
|
|
|
|
return indexOf && samePath ? basePath : path.resolve(basePath, routePath) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getOnlyChild(item) { |
|
|
|
|
|
|
|
const showingChildren = item.children || [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (showingChildren.length === 1) return showingChildren[0] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (showingChildren.length <= 0) return {...item, path: undefined, children: undefined} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export default { |
|
|
|
export default { |
|
|
|
name: 'SidebarItem', |
|
|
|
functional: true, |
|
|
|
inject: ['rootMenu'], |
|
|
|
|
|
|
|
components: {SidebarItemContent}, |
|
|
|
|
|
|
|
props: { |
|
|
|
props: { |
|
|
|
item: Object, |
|
|
|
item: Object, |
|
|
|
isNest: Boolean, |
|
|
|
isNest: Boolean, |
|
|
|
showParent: Boolean, |
|
|
|
showParent: Boolean, |
|
|
|
basePath: { |
|
|
|
collapse: Boolean, |
|
|
|
type: String, |
|
|
|
basePath: {type: String, default: ''} |
|
|
|
default: '' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
data: () => ({onlyOneChild: {}}), |
|
|
|
|
|
|
|
methods: { |
|
|
|
|
|
|
|
resolvePath(routePath = '') { |
|
|
|
|
|
|
|
const indexOf = this.basePath.indexOf(routePath) |
|
|
|
|
|
|
|
if (indexOf > 0 && this.basePath.length === indexOf + routePath.length) { |
|
|
|
|
|
|
|
return this.basePath |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return path.resolve(this.basePath, routePath) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
render() { |
|
|
|
render(h, context) { |
|
|
|
const hasOnlyOneShowingChild = () => { |
|
|
|
function renderNode({item, isNest, showParent, collapse, basePath}) { |
|
|
|
const showingChildren = this.item.children || [] |
|
|
|
let onlyOneChild = getOnlyChild(item) |
|
|
|
|
|
|
|
|
|
|
|
if (showingChildren.length === 1) { |
|
|
|
const showSingle = onlyOneChild && !onlyOneChild.children && !item.alwaysShow |
|
|
|
this.onlyOneChild = showingChildren[0] |
|
|
|
|
|
|
|
return true |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (showingChildren.length <= 0) { |
|
|
|
if (showSingle) { |
|
|
|
this.onlyOneChild = {...this.item, path: undefined, children: undefined} |
|
|
|
const index = resolvePath(basePath, onlyOneChild.path) |
|
|
|
return true |
|
|
|
const icon = onlyOneChild.meta.icon || (item.meta && item.meta.icon) |
|
|
|
|
|
|
|
const title = onlyOneChild.meta.title |
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
|
|
<el-menu-item |
|
|
|
|
|
|
|
index={index} |
|
|
|
|
|
|
|
class={{'submenu-title-noDropdown': !isNest, 'nest-menu': isNest}} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<SidebarItemContent icon={icon} title={title}/> |
|
|
|
|
|
|
|
</el-menu-item> |
|
|
|
|
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
const index = resolvePath(basePath, item.path) |
|
|
|
|
|
|
|
const icon = (item.meta && item.meta.icon) || (onlyOneChild.meta && onlyOneChild.meta.icon) |
|
|
|
|
|
|
|
const title = item.meta.title |
|
|
|
|
|
|
|
|
|
|
|
return false |
|
|
|
const children = item.children.map(child => renderNode({ |
|
|
|
} |
|
|
|
isNest: true, |
|
|
|
const showSingle = () => { |
|
|
|
item: child, |
|
|
|
return hasOnlyOneShowingChild() && (!this.onlyOneChild.children) && !this.item.alwaysShow |
|
|
|
basePath: resolvePath(basePath, child.path), |
|
|
|
} |
|
|
|
showParent, |
|
|
|
if (showSingle()) { |
|
|
|
collapse |
|
|
|
const index = this.resolvePath(this.onlyOneChild.path) |
|
|
|
})) |
|
|
|
const icon = this.onlyOneChild.meta.icon || (this.item.meta && this.item.meta.icon) |
|
|
|
|
|
|
|
const title = this.onlyOneChild.meta.title |
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
|
|
<el-menu-item index={index} class={{'submenu-title-noDropdown': !this.isNest}}> |
|
|
|
|
|
|
|
<sidebar-item-content icon={icon} title={title}/> |
|
|
|
|
|
|
|
</el-menu-item> |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
const index = this.resolvePath(this.item.path) |
|
|
|
|
|
|
|
const icon = (this.item.meta && this.item.meta.icon) || (this.onlyOneChild.meta && this.onlyOneChild.meta.icon) |
|
|
|
|
|
|
|
const title = this.item.meta.title |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const children = this.item.children.map(child => ( |
|
|
|
//弹出菜单如果包裹滚动条,则在触发mouseleave时,不会触发父菜单的mouseleave事件 |
|
|
|
<sidebar-item |
|
|
|
if (collapse) { |
|
|
|
is-nest |
|
|
|
//弹出菜单显示父级信息 |
|
|
|
item={child} |
|
|
|
if (showParent) { |
|
|
|
base-path={this.resolvePath(child.path)} |
|
|
|
children.unshift( |
|
|
|
class="nest-menu" |
|
|
|
<el-menu-item class="popover-menu__title" disabled> |
|
|
|
/> |
|
|
|
<SidebarItemContent icon={icon} title={title}/> |
|
|
|
)) |
|
|
|
</el-menu-item> |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//弹出菜单包裹滚动条 |
|
|
|
return ( |
|
|
|
const popoverMenu = [<el-scrollbar wrap-class="popover-menu__wrap">{children}</el-scrollbar>] |
|
|
|
<el-submenu class={{'nest-menu': isNest}} index={index} popper-append-to-body> |
|
|
|
|
|
|
|
<SidebarItemContent slot="title" icon={icon} title={title}/> |
|
|
|
//弹出菜单显示父级信息 |
|
|
|
{children} |
|
|
|
if (this.rootMenu.collapse && this.showParent) { |
|
|
|
</el-submenu> |
|
|
|
popoverMenu.unshift( |
|
|
|
|
|
|
|
<el-menu-item class="popover-menu__title" disabled> |
|
|
|
|
|
|
|
<sidebar-item-content icon={icon} title={title}/> |
|
|
|
|
|
|
|
</el-menu-item> |
|
|
|
|
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
//外面需要额外包裹一层,否则el-submenu调用this.$parent.$el.dispatch时会死循环 |
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
|
|
<li> |
|
|
|
|
|
|
|
<el-submenu index={index} popper-append-to-body> |
|
|
|
|
|
|
|
<sidebar-item-content slot="title" icon={icon} title={title}/> |
|
|
|
|
|
|
|
{this.rootMenu.collapse ? popoverMenu : children} |
|
|
|
|
|
|
|
</el-submenu> |
|
|
|
|
|
|
|
</li> |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return renderNode(context.props) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|