feat 四级路由刷新优化
This commit is contained in:
parent
8cc09fa77d
commit
3dbfb97137
@ -51,13 +51,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="navMenuHorizontal">
|
||||
import { defineAsyncComponent, reactive, computed, onBeforeMount } from 'vue'
|
||||
import { reactive, computed, onBeforeMount } from 'vue'
|
||||
import { useRoute, onBeforeRouteUpdate, RouteRecordRaw, useRouter } from 'vue-router'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoutesList } from '/@/stores/routesList'
|
||||
import { useThemeConfig } from '/@/stores/themeConfig'
|
||||
import other from '/@/utils/other'
|
||||
import mittBus from '/@/utils/mitt'
|
||||
import { treeToList, listToTree, filterList } from '/@/utils/tree'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
@ -65,9 +64,6 @@ import { cloneDeep } from 'lodash-es'
|
||||
const router = useRouter()
|
||||
const { t } = useI18n()
|
||||
|
||||
// 引入组件
|
||||
// const SubItem = defineAsyncComponent(() => import('/@/layout/navMenu/subItem.vue')) // 使用el-dropdown替代
|
||||
|
||||
// 定义父组件传过来的值
|
||||
const props = defineProps({
|
||||
// 菜单列表
|
||||
@ -109,8 +105,6 @@ const currentModule = computed(() => {
|
||||
route.path.startsWith(module.path)
|
||||
)
|
||||
|
||||
console.log('state.currentModulePath', state.currentModulePath)
|
||||
|
||||
return current || moduleList.value[0] || {
|
||||
path: '',
|
||||
title: '选择模块',
|
||||
@ -178,29 +172,54 @@ const setCurrentRouterHighlight = (currentRoute: RouteToFrom) => {
|
||||
|
||||
// 处理模块切换命令
|
||||
const onModuleCommand = (path: string) => {
|
||||
console.log('🎯 [Horizontal Menu] onModuleCommand - 模块切换:', {
|
||||
selectedPath: path,
|
||||
currentModulePath: state.currentModulePath
|
||||
})
|
||||
|
||||
// 更新当前模块路径
|
||||
state.currentModulePath = path
|
||||
console.log('🎯 [Horizontal Menu] onModuleCommand - 更新当前模块路径:', state.currentModulePath)
|
||||
|
||||
// 查找选中的模块
|
||||
const selectedModule = menuLists.value.find(item => item.path === path)
|
||||
console.log('🎯 [Horizontal Menu] onModuleCommand - 查找选中模块:', {
|
||||
selectedModule: selectedModule ? {
|
||||
path: selectedModule.path,
|
||||
title: selectedModule.meta?.title,
|
||||
hasChildren: !!selectedModule.children,
|
||||
childrenLength: selectedModule.children?.length || 0
|
||||
} : null
|
||||
})
|
||||
|
||||
if (!selectedModule) return
|
||||
|
||||
// 如果模块有子菜单,跳转到第一个可用的子菜单,并更新左侧菜单为第三级
|
||||
if (selectedModule.children && selectedModule.children.length > 0) {
|
||||
const firstChild = selectedModule.children.find((child: RouteRecordRaw) => !child.meta?.isHide)
|
||||
console.log('🎯 [Horizontal Menu] onModuleCommand - 查找第一个子菜单:', {
|
||||
firstChild: firstChild ? {
|
||||
path: firstChild.path,
|
||||
title: firstChild.meta?.title,
|
||||
isHide: firstChild.meta?.isHide
|
||||
} : null
|
||||
})
|
||||
|
||||
if (firstChild) {
|
||||
console.log('🎯 [Horizontal Menu] onModuleCommand - 跳转到子菜单:', firstChild.path)
|
||||
router.push(firstChild.path)
|
||||
console.log('onModuleCommand setSendColumnsChildren1', firstChild.path)
|
||||
// 更新左侧显示为第三级菜单
|
||||
mittBus.emit('setSendColumnsChildren', setSendSubMenuChildren(firstChild.path))
|
||||
const subMenuData = setSendSubMenuChildren(firstChild.path)
|
||||
console.log('🎯 [Horizontal Menu] onModuleCommand - 发送子菜单数据:', subMenuData)
|
||||
mittBus.emit('setSendColumnsChildren', subMenuData)
|
||||
} else {
|
||||
console.log('🎯 [Horizontal Menu] onModuleCommand - 无可用子菜单,跳转到模块根路径:', selectedModule.path)
|
||||
router.push(selectedModule.path)
|
||||
console.log('onModuleCommand setSendColumnsChildren2', firstChild.path)
|
||||
mittBus.emit('setSendColumnsChildren', { children: [] })
|
||||
}
|
||||
} else {
|
||||
console.log('🎯 [Horizontal Menu] onModuleCommand - 模块无子菜单,跳转到模块路径:', selectedModule.path)
|
||||
router.push(selectedModule.path)
|
||||
console.log('onModuleCommand setSendColumnsChildren3', selectedModule.path)
|
||||
mittBus.emit('setSendColumnsChildren', { children: [] })
|
||||
}
|
||||
}
|
||||
@ -235,26 +254,151 @@ const setSendSubMenuChildren = (path: string) => {
|
||||
}
|
||||
|
||||
const setBeforeRouteUpdateClassicChildren = (path: string) => {
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 开始解析路径:', {
|
||||
targetPath: path,
|
||||
currentModulePath: state.currentModulePath
|
||||
})
|
||||
|
||||
let res: MittMenu = { children: [] }
|
||||
|
||||
// 解析路径层级
|
||||
const pathSegments = path.split('/').filter(Boolean)
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 路径分割:', {
|
||||
pathSegments,
|
||||
level: pathSegments.length
|
||||
})
|
||||
|
||||
//解析菜单路径
|
||||
const module = menuLists.value.find(item => item.path === state.currentModulePath)
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 查找模块:', {
|
||||
module: module ? {
|
||||
path: module.path,
|
||||
title: module.meta?.title,
|
||||
hasChildren: !!module.children,
|
||||
childrenCount: module.children?.length || 0
|
||||
} : null
|
||||
})
|
||||
|
||||
if (module && module.children) {
|
||||
const sub = module.children.find((child: RouteRecordRaw) => path.startsWith(child.path))
|
||||
if (sub) {
|
||||
res.item = { ...sub }
|
||||
res.children = sub.children ? [...sub.children] : []
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 模块子菜单列表:',
|
||||
module.children.map((child: RouteRecordRaw) => ({
|
||||
path: child.path,
|
||||
title: child.meta?.title,
|
||||
pathStartsWithTarget: path.startsWith(child.path)
|
||||
}))
|
||||
)
|
||||
|
||||
// 递归查找匹配的菜单项,返回其父级的children
|
||||
const findMatchingMenuAndParent = (menuItems: RouteRecordRaw[], targetPath: string, depth: number = 0): { parent: RouteRecordRaw | null, matchedItem: RouteRecordRaw | null } => {
|
||||
console.log(`🔧 [Horizontal Menu] findMatchingMenuAndParent - 第${depth}层查找:`, {
|
||||
menuItemsCount: menuItems.length,
|
||||
targetPath
|
||||
})
|
||||
|
||||
for (const item of menuItems) {
|
||||
console.log(`🔧 [Horizontal Menu] findMatchingMenuAndParent - 检查菜单项:`, {
|
||||
itemPath: item.path,
|
||||
targetPath,
|
||||
exactMatch: item.path === targetPath,
|
||||
startsWithMatch: targetPath.startsWith(item.path),
|
||||
hasChildren: !!item.children
|
||||
})
|
||||
|
||||
// 精确匹配当前路径
|
||||
if (item.path === targetPath) {
|
||||
console.log(`🔧 [Horizontal Menu] findMatchingMenuAndParent - 找到精确匹配:`, {
|
||||
matchedPath: item.path,
|
||||
title: item.meta?.title,
|
||||
hasChildren: !!item.children,
|
||||
childrenCount: item.children?.length || 0
|
||||
})
|
||||
return { parent: null, matchedItem: item }
|
||||
}
|
||||
|
||||
// 如果当前路径是某个菜单项的子路径,且该菜单项有子菜单
|
||||
if (targetPath.startsWith(item.path) && item.children && item.children.length > 0) {
|
||||
console.log(`🔧 [Horizontal Menu] findMatchingMenuAndParent - 路径匹配,递归查找子菜单:`, {
|
||||
parentPath: item.path,
|
||||
parentTitle: item.meta?.title
|
||||
})
|
||||
|
||||
const result = findMatchingMenuAndParent(item.children, targetPath, depth + 1)
|
||||
if (result.matchedItem) {
|
||||
// 如果在子菜单中找到了匹配项,返回当前项作为父级
|
||||
return { parent: item, matchedItem: result.matchedItem }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { parent: null, matchedItem: null }
|
||||
}
|
||||
|
||||
const { parent, matchedItem } = findMatchingMenuAndParent(module.children, path)
|
||||
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 匹配结果:', {
|
||||
matchedItem: matchedItem ? {
|
||||
path: matchedItem.path,
|
||||
title: matchedItem.meta?.title,
|
||||
hasChildren: !!matchedItem.children,
|
||||
childrenCount: matchedItem.children?.length || 0
|
||||
} : null,
|
||||
parent: parent ? {
|
||||
path: parent.path,
|
||||
title: parent.meta?.title,
|
||||
hasChildren: !!parent.children,
|
||||
childrenCount: parent.children?.length || 0
|
||||
} : null
|
||||
})
|
||||
|
||||
if (matchedItem) {
|
||||
// 如果有父级,显示父级的children(即匹配项的同级菜单)
|
||||
// 如果没有父级,显示匹配项的children(即子菜单)
|
||||
if (parent) {
|
||||
res.item = { ...parent } as RouteItem
|
||||
res.children = parent.children ? [...parent.children] as RouteItem[] : []
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 使用父级菜单的children:', {
|
||||
parentPath: parent.path,
|
||||
parentTitle: parent.meta?.title,
|
||||
childrenCount: res.children.length
|
||||
})
|
||||
} else {
|
||||
res.item = { ...matchedItem } as RouteItem
|
||||
res.children = matchedItem.children ? [...matchedItem.children] as RouteItem[] : []
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 使用匹配项的children:', {
|
||||
itemPath: matchedItem.path,
|
||||
itemTitle: matchedItem.meta?.title,
|
||||
childrenCount: res.children.length
|
||||
})
|
||||
}
|
||||
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 构建结果数据:', {
|
||||
itemPath: res.item?.path,
|
||||
itemTitle: res.item?.meta?.title,
|
||||
childrenCount: res.children?.length || 0,
|
||||
children: res.children?.map(c => ({ path: c.path, title: c.meta?.title })) || []
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🔧 [Horizontal Menu] setBeforeRouteUpdateClassicChildren - 最终返回数据:', res)
|
||||
return res
|
||||
}
|
||||
|
||||
// 新增:二级菜单点击处理
|
||||
const onSubMenuClick = (path: string) => {
|
||||
console.log('📋 [Horizontal Menu] onSubMenuClick - 二级菜单点击:', {
|
||||
clickedPath: path,
|
||||
currentRoute: route.path,
|
||||
currentModule: state.currentModulePath
|
||||
})
|
||||
|
||||
// 跳转到选中的二级路由
|
||||
console.log('📋 [Horizontal Menu] onSubMenuClick - 执行路由跳转:', path)
|
||||
router.push(path)
|
||||
mittBus.emit('setSendColumnsChildren', setSendSubMenuChildren(path))
|
||||
|
||||
const subMenuData = setSendSubMenuChildren(path)
|
||||
console.log('📋 [Horizontal Menu] onSubMenuClick - 发送子菜单数据到左侧:', subMenuData)
|
||||
mittBus.emit('setSendColumnsChildren', subMenuData)
|
||||
}
|
||||
|
||||
// 判断是否为当前模块
|
||||
@ -263,41 +407,94 @@ const isCurrentModule = (path: string): boolean => {
|
||||
}
|
||||
// 页面加载前
|
||||
onBeforeMount(() => {
|
||||
console.log('🚀 [Horizontal Menu] onBeforeMount - 页面加载前初始化:', {
|
||||
currentRoute: route.path,
|
||||
menuListsLength: menuLists.value?.length || 0
|
||||
})
|
||||
|
||||
setCurrentRouterHighlight(route)
|
||||
console.log('🚀 [Horizontal Menu] onBeforeMount - 设置路由高亮完成')
|
||||
|
||||
// 初始化当前模块
|
||||
initCurrentModule()
|
||||
console.log('🚀 [Horizontal Menu] onBeforeMount - 初始化完成:', {
|
||||
currentModulePath: state.currentModulePath,
|
||||
defaultActive: state.defaultActive
|
||||
})
|
||||
|
||||
// 初始化完成后,主动发送当前路由对应的子菜单数据
|
||||
const classicChildrenData = setBeforeRouteUpdateClassicChildren(route.path)
|
||||
console.log('🚀 [Horizontal Menu] onBeforeMount - 发送初始子菜单数据:', {
|
||||
currentPath: route.path,
|
||||
data: classicChildrenData
|
||||
})
|
||||
mittBus.emit('setSendColumnsChildren', classicChildrenData)
|
||||
})
|
||||
|
||||
// 初始化当前模块
|
||||
const initCurrentModule = () => {
|
||||
console.log('🚀 [Horizontal Menu] initCurrentModule - 初始化当前模块:', {
|
||||
currentPath: route.path,
|
||||
availableModules: menuLists.value.map(m => ({ path: m.path, title: m.meta?.title }))
|
||||
})
|
||||
|
||||
// 根据当前路由确定所属模块
|
||||
const currentPath = route.path
|
||||
const matchedModule = menuLists.value.find(module =>
|
||||
currentPath.startsWith(module.path) && module.path !== '/'
|
||||
)
|
||||
|
||||
console.log('🚀 [Horizontal Menu] initCurrentModule - 模块匹配结果:', {
|
||||
matchedModule: matchedModule ? {
|
||||
path: matchedModule.path,
|
||||
title: matchedModule.meta?.title
|
||||
} : null
|
||||
})
|
||||
|
||||
if (matchedModule) {
|
||||
state.currentModulePath = matchedModule.path
|
||||
console.log('🚀 [Horizontal Menu] initCurrentModule - 设置匹配的模块:', state.currentModulePath)
|
||||
} else if (menuLists.value.length > 0) {
|
||||
// 如果没有匹配的模块,默认选择第一个
|
||||
state.currentModulePath = menuLists.value[0].path
|
||||
console.log('🚀 [Horizontal Menu] initCurrentModule - 设置默认模块:', state.currentModulePath)
|
||||
}
|
||||
}
|
||||
|
||||
// 路由更新时
|
||||
onBeforeRouteUpdate((to) => {
|
||||
console.log('🔄 [Horizontal Menu] onBeforeRouteUpdate - 路由更新开始:', {
|
||||
from: route.path,
|
||||
to: to.path,
|
||||
toMeta: to.meta
|
||||
})
|
||||
|
||||
// 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
|
||||
setCurrentRouterHighlight(to)
|
||||
|
||||
// 更新当前模块
|
||||
const matchedModule = menuLists.value.find(module =>
|
||||
to.path.startsWith(module.path) && module.path !== '/'
|
||||
)
|
||||
console.log('🔄 [Horizontal Menu] onBeforeRouteUpdate - 匹配模块:', {
|
||||
matchedModule: matchedModule ? {
|
||||
path: matchedModule.path,
|
||||
title: matchedModule.meta?.title
|
||||
} : null,
|
||||
previousModule: state.currentModulePath
|
||||
})
|
||||
|
||||
if (matchedModule) {
|
||||
state.currentModulePath = matchedModule.path
|
||||
console.log('🔄 [Horizontal Menu] onBeforeRouteUpdate - 更新当前模块路径:', state.currentModulePath)
|
||||
}
|
||||
|
||||
console.log('onBeforeRouteUpdate', to.path, matchedModule.path)
|
||||
mittBus.emit('setSendClassicChildren', setBeforeRouteUpdateClassicChildren(to.path))
|
||||
|
||||
const classicChildrenData = setBeforeRouteUpdateClassicChildren(to.path)
|
||||
console.log('🔄 [Horizontal Menu] onBeforeRouteUpdate - 发送经典布局子级数据:', {
|
||||
targetPath: to.path,
|
||||
data: classicChildrenData
|
||||
})
|
||||
mittBus.emit('setSendClassicChildren', classicChildrenData)
|
||||
|
||||
// // 修复经典布局开启切割菜单时,点击tagsView后左侧导航菜单数据不变的问题
|
||||
// let { layout, isClassicSplitMenu } = themeConfig.value
|
||||
|
@ -3,7 +3,7 @@
|
||||
<el-sub-menu :index="val.path" :key="val.path" v-if="val.children && val.children.length > 0">
|
||||
<template #title>
|
||||
<SvgIcon :name="val.meta.icon" />
|
||||
<span>{{ $t(val.meta.title) + '12345' }}</span>
|
||||
<span>{{ $t(val.meta.title) }}</span>
|
||||
</template>
|
||||
<sub-item :chil="val.children" />
|
||||
</el-sub-menu>
|
||||
@ -11,7 +11,7 @@
|
||||
<el-menu-item :index="val.path" :key="val.path">
|
||||
<template v-if="!val.meta.isLink || (val.meta.isLink && val.meta.isIframe)">
|
||||
<SvgIcon :name="val.meta.icon" />
|
||||
<span>{{ $t(val.meta.title) + '123456' }}</span>
|
||||
<span>{{ $t(val.meta.title) }}</span>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
@ -33,7 +33,16 @@ const props = defineProps({
|
||||
|
||||
// 获取父级菜单数据
|
||||
const chils = computed(() => {
|
||||
console.log('chils', props.chil)
|
||||
console.log('🔗 [Sub Item] 子菜单数据更新:', {
|
||||
childrenCount: props.chil?.length || 0,
|
||||
children: props.chil?.map(item => ({
|
||||
path: item.path,
|
||||
title: item.meta?.title,
|
||||
icon: item.meta?.icon,
|
||||
hasChildren: !!(item.children && item.children.length > 0),
|
||||
childrenCount: item.children?.length || 0
|
||||
})) || []
|
||||
})
|
||||
return <RouteItems>props.chil
|
||||
})
|
||||
</script>
|
||||
|
@ -81,7 +81,13 @@ watch(
|
||||
|
||||
// 订阅水平菜单发送的菜单数据
|
||||
mittBus.on('setSendColumnsChildren', (res) => {
|
||||
console.log('📨 [Vertical Menu] 接收到水平菜单数据:', {
|
||||
event: 'setSendColumnsChildren',
|
||||
data: res,
|
||||
childrenLength: res.children?.length || 0
|
||||
})
|
||||
localMenuList.value = res.children || []
|
||||
console.log('📨 [Vertical Menu] 更新本地菜单列表:', localMenuList.value?.length)
|
||||
})
|
||||
|
||||
// 获取父级菜单数据
|
||||
@ -93,9 +99,27 @@ const getThemeConfig = computed(() => {
|
||||
// 菜单高亮(详情时,父级高亮)
|
||||
const setParentHighlight = (currentRoute: RouteToFrom) => {
|
||||
const { path, meta } = currentRoute
|
||||
console.log('🔍 [Vertical Menu] setParentHighlight - 路由信息:', {
|
||||
path,
|
||||
meta,
|
||||
isDynamic: meta?.isDynamic,
|
||||
isDynamicPath: meta?.isDynamicPath,
|
||||
isHide: meta?.isHide
|
||||
})
|
||||
|
||||
const pathSplit = meta?.isDynamic ? meta.isDynamicPath!.split('/') : path!.split('/')
|
||||
if (pathSplit.length >= 4 && meta?.isHide) return pathSplit.splice(0, 3).join('/')
|
||||
else return path
|
||||
console.log('🔍 [Vertical Menu] setParentHighlight - 路径分割:', pathSplit)
|
||||
|
||||
let highlightPath = ''
|
||||
if (pathSplit.length >= 4 && meta?.isHide) {
|
||||
highlightPath = pathSplit.splice(0, 3).join('/')
|
||||
console.log('🔍 [Vertical Menu] setParentHighlight - 隐藏路由高亮父级:', highlightPath)
|
||||
} else {
|
||||
highlightPath = path!
|
||||
console.log('🔍 [Vertical Menu] setParentHighlight - 常规路由高亮:', highlightPath)
|
||||
}
|
||||
|
||||
return highlightPath
|
||||
}
|
||||
// 打开外部链接
|
||||
const onALinkClick = (val: RouteItem) => {
|
||||
@ -103,12 +127,28 @@ const onALinkClick = (val: RouteItem) => {
|
||||
}
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
console.log('🚀 [Vertical Menu] onMounted - 初始化菜单:', {
|
||||
currentRoute: route.path,
|
||||
menuLists: menuLists.value?.length
|
||||
})
|
||||
state.defaultActive = setParentHighlight(route)
|
||||
console.log('🚀 [Vertical Menu] onMounted - 设置默认激活菜单:', state.defaultActive)
|
||||
})
|
||||
// 路由更新时
|
||||
onBeforeRouteUpdate((to) => {
|
||||
console.log('🔄 [Vertical Menu] onBeforeRouteUpdate - 路由更新:', {
|
||||
from: route.path,
|
||||
to: to.path,
|
||||
meta: to.meta
|
||||
})
|
||||
state.defaultActive = setParentHighlight(to)
|
||||
console.log('🔄 [Vertical Menu] onBeforeRouteUpdate - 更新默认激活菜单:', state.defaultActive)
|
||||
|
||||
const clientWidth = document.body.clientWidth
|
||||
console.log('🔄 [Vertical Menu] onBeforeRouteUpdate - 屏幕宽度检查:', {
|
||||
clientWidth,
|
||||
needCollapse: clientWidth < 1000
|
||||
})
|
||||
if (clientWidth < 1000) themeConfig.value.isCollapse = false
|
||||
})
|
||||
// 设置菜单的收起/展开
|
||||
|
Loading…
x
Reference in New Issue
Block a user