fix: 修复菜单显示错误问题

修复菜单显示错误问题
pull/305/head
glacier 2023-11-02 17:59:02 +08:00
parent 309c3f30d1
commit e4e6ee9afa
3 changed files with 48 additions and 88 deletions

View File

@ -1,54 +1,64 @@
import { ElSubMenu, ElMenuItem } from 'element-plus'
import type { RouteMeta } from 'vue-router'
import { hasOneShowingChild } from '../helper'
import { isUrl } from '@/utils/is'
import { useRenderMenuTitle } from './useRenderMenuTitle'
import { useDesign } from '@/hooks/web/useDesign'
import { pathResolve } from '@/utils/routerHelper'
export const useRenderMenuItem = (
// allRouters: AppRouteRecordRaw[] = [],
menuMode: 'vertical' | 'horizontal'
) => {
export const useRenderMenuItem = (menuMode: 'vertical' | 'horizontal') => {
const { renderMenuTitle } = useRenderMenuTitle()
const { getPrefixCls } = useDesign()
const preFixCls = getPrefixCls('menu-popper')
const renderMenuItemTitle = (router: AppRouteRecordRaw, fullPath: string) => {
return (
<ElMenuItem index={fullPath}>
{{
default: () => renderMenuTitle(router?.meta)
}}
</ElMenuItem>
)
}
const renderMenuItemWithChildren = (router: AppRouteRecordRaw, fullPath: string) => {
return (
<ElSubMenu
index={fullPath}
popperClass={
menuMode === 'vertical' ? `${preFixCls}--vertical` : `${preFixCls}--horizontal`
}
>
{{
title: () => renderMenuTitle(router.meta),
default: () => renderMenuItem(router.children!, fullPath)
}}
</ElSubMenu>
)
}
const renderMenuItem = (routers: AppRouteRecordRaw[], parentPath = '/') => {
return routers.map((v) => {
const meta = (v.meta ?? {}) as RouteMeta
if (!meta.hidden) {
const { oneShowingChild, onlyOneChild } = hasOneShowingChild(v.children, v)
const fullPath = isUrl(v.path) ? v.path : pathResolve(parentPath, v.path) // getAllParentPath<AppRouteRecordRaw>(allRouters, v.path).join('/')
const { children = [] } = v
const { renderMenuTitle } = useRenderMenuTitle()
const showingChildren = children.filter((v) => !v.meta.hidden)
if (
oneShowingChild &&
(!onlyOneChild?.children || onlyOneChild?.noShowingChildren) &&
!meta?.alwaysShow
) {
return (
<ElMenuItem index={onlyOneChild ? pathResolve(fullPath, onlyOneChild.path) : fullPath}>
{{
default: () => renderMenuTitle(onlyOneChild ? onlyOneChild?.meta : meta)
}}
</ElMenuItem>
)
} else {
const { getPrefixCls } = useDesign()
const fullPath = isUrl(v.path) ? v.path : pathResolve(parentPath, v.path)
const preFixCls = getPrefixCls('menu-popper')
return (
<ElSubMenu
index={fullPath}
popperClass={
menuMode === 'vertical' ? `${preFixCls}--vertical` : `${preFixCls}--horizontal`
}
>
{{
title: () => renderMenuTitle(meta),
default: () => renderMenuItem(v.children!, fullPath)
}}
</ElSubMenu>
)
if (!showingChildren.length) {
return renderMenuItemTitle(v, fullPath)
}
if (showingChildren.length === 1 && !meta?.alwaysShow) {
const child = showingChildren[0]
const childFullPath = isUrl(child.path) ? child.path : pathResolve(fullPath, child.path)
if (!child.children) {
return renderMenuItemTitle(child, childFullPath)
} else {
return renderMenuItemWithChildren(child, childFullPath)
}
}
return renderMenuItemWithChildren(v, fullPath)
}
})
}

View File

@ -1,54 +1,6 @@
import type { RouteMeta } from 'vue-router'
import { findPath } from '@/utils/tree'
type OnlyOneChildType = AppRouteRecordRaw & { noShowingChildren?: boolean }
interface HasOneShowingChild {
oneShowingChild?: boolean
onlyOneChild?: OnlyOneChildType
}
export const getAllParentPath = <T = Recordable>(treeData: T[], path: string) => {
const menuList = findPath(treeData, (n) => n.path === path) as AppRouteRecordRaw[]
return (menuList || []).map((item) => item.path)
}
export const hasOneShowingChild = (
children: AppRouteRecordRaw[] = [],
parent: AppRouteRecordRaw
): HasOneShowingChild => {
const onlyOneChild = ref<OnlyOneChildType>()
const showingChildren = children.filter((v) => {
const meta = (v.meta ?? {}) as RouteMeta
if (meta.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
onlyOneChild.value = v
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return {
oneShowingChild: true,
onlyOneChild: unref(onlyOneChild)
}
}
// Show parent if there are no child router to display
if (!showingChildren.length) {
onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
return {
oneShowingChild: true,
onlyOneChild: unref(onlyOneChild)
}
}
return {
oneShowingChild: false,
onlyOneChild: unref(onlyOneChild)
}
}

View File

@ -69,11 +69,9 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord
icon: route.icon,
hidden: !route.visible,
noCache: !route.keepAlive,
alwaysShow:
route.children &&
route.children.length === 1 &&
(route.alwaysShow !== undefined ? route.alwaysShow : true)
alwaysShow: !!route.alwaysShow
}
// 路由地址转首字母大写驼峰作为路由名称适配keepAlive
let data: AppRouteRecordRaw = {
path: route.path,