feat 修改三级路由跳转问题
This commit is contained in:
parent
b8c8d403db
commit
df35c72dae
@ -82,21 +82,7 @@ const closeLayoutAsideMobileMode = () => {
|
||||
if (clientWidth < 1000) themeConfig.value.isCollapse = false
|
||||
document.body.setAttribute('class', '')
|
||||
}
|
||||
// 设置/过滤路由(非静态路由/是否显示在菜单中)
|
||||
const setFilterRoutes = () => {
|
||||
if (themeConfig.value.layout === 'columns') return false
|
||||
state.menuList = filterRoutesFun(routesList.value)
|
||||
}
|
||||
// 路由过滤递归函数
|
||||
const filterRoutesFun = <T extends RouteItem>(arr: T[]): T[] => {
|
||||
return arr
|
||||
.filter((item: T) => !item.meta?.isHide)
|
||||
.map((item: T) => {
|
||||
item = Object.assign({}, item)
|
||||
if (item.children) item.children = filterRoutesFun(item.children)
|
||||
return item
|
||||
})
|
||||
}
|
||||
|
||||
// 设置菜单导航是否固定(移动端)
|
||||
const initMenuFixed = (clientWidth: number) => {
|
||||
state.clientWidth = clientWidth
|
||||
@ -112,15 +98,16 @@ const onAsideEnterLeave = (bool: Boolean) => {
|
||||
// 页面加载前
|
||||
onBeforeMount(() => {
|
||||
initMenuFixed(document.body.clientWidth)
|
||||
setFilterRoutes()
|
||||
// 此界面不需要取消监听(mittBus.off('setSendColumnsChildren))
|
||||
// 因为切换布局时有的监听需要使用,取消了监听,某些操作将不生效
|
||||
mittBus.on('setSendColumnsChildren', (res: MittMenu) => {
|
||||
console.log('setSendColumnsChildren', res)
|
||||
!res.children || res.children.length < 1 ? (themeConfig.value.isCollapse = true) : (themeConfig.value.isCollapse = false)
|
||||
state.menuList = res.children
|
||||
})
|
||||
// 开启经典布局分割菜单时,设置菜单数据
|
||||
mittBus.on('setSendClassicChildren', (res: MittMenu) => {
|
||||
console.log('setSendClassicChildren', res)
|
||||
let { layout, isClassicSplitMenu } = themeConfig.value
|
||||
if (layout === 'classic' && isClassicSplitMenu) {
|
||||
// 经典布局分割菜单只有一项子级时,收起左侧导航菜单
|
||||
@ -131,10 +118,6 @@ onBeforeMount(() => {
|
||||
state.menuList = res.children
|
||||
}
|
||||
})
|
||||
// 开启经典布局分割菜单时,重新处理菜单数据
|
||||
mittBus.on('getBreadcrumbIndexSetFilterRoutes', () => {
|
||||
setFilterRoutes()
|
||||
})
|
||||
// 监听窗口大小改变时(适配移动端)
|
||||
mittBus.on('layoutMobileResize', (res: LayoutMobileResize) => {
|
||||
initMenuFixed(res.clientWidth)
|
||||
@ -157,11 +140,17 @@ watch(
|
||||
if (layout === 'classic' && isClassicSplitMenu) return false
|
||||
}
|
||||
)
|
||||
// 监听用户权限切换,用于演示 `权限管理 -> 前端控制 -> 页面权限` 权限切换不生效
|
||||
// 监听路由列表变化,根据布局更新侧边菜单(默认布局由顶部导航控制)
|
||||
watch(
|
||||
() => routesList.value,
|
||||
() => {
|
||||
setFilterRoutes()
|
||||
}
|
||||
// 在默认布局(水平模式)下,不自动恢复为二级菜单,以保留顶部导航控制的三级菜单
|
||||
if (themeConfig.value.layout === 'defaults') return
|
||||
// 当路由数据加载完成时,确保停止加载动画
|
||||
if (routesList.value.length > 0) {
|
||||
layoutAsideScrollbarRef.value?.update()
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
</script>
|
||||
|
@ -17,6 +17,7 @@
|
||||
<span>{{ $t(item.meta?.title) }}</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
|
||||
<!-- 将四个模块合并为一个下拉菜单,类似语言切换 -->
|
||||
<el-dropdown
|
||||
:show-timeout="70"
|
||||
@ -185,33 +186,24 @@ const onModuleCommand = (path: string) => {
|
||||
const selectedModule = menuLists.value.find(item => item.path === path)
|
||||
if (!selectedModule) return
|
||||
|
||||
// 如果是外部链接,使用原有的处理方式
|
||||
if (selectedModule.meta?.isLink && !selectedModule.meta?.isIframe) {
|
||||
onALinkClick(selectedModule)
|
||||
return
|
||||
}
|
||||
|
||||
// 如果模块有子菜单,跳转到第一个可用的子菜单,并更新左侧菜单
|
||||
// 如果模块有子菜单,跳转到第一个可用的子菜单,并更新左侧菜单为第三级
|
||||
if (selectedModule.children && selectedModule.children.length > 0) {
|
||||
const firstChild = selectedModule.children.find((child: RouteItem) => !child.meta?.isHide)
|
||||
const firstChild = selectedModule.children.find((child: RouteRecordRaw) => !child.meta?.isHide)
|
||||
if (firstChild) {
|
||||
router.push(firstChild.path)
|
||||
// 更新左侧显示二级子菜单的子项
|
||||
console.log('onModuleCommand setSendColumnsChildren1', firstChild.path)
|
||||
// 更新左侧显示为第三级菜单
|
||||
mittBus.emit('setSendColumnsChildren', setSendSubMenuChildren(firstChild.path))
|
||||
} else {
|
||||
router.push(selectedModule.path)
|
||||
console.log('onModuleCommand setSendColumnsChildren2', firstChild.path)
|
||||
mittBus.emit('setSendColumnsChildren', { children: [] })
|
||||
}
|
||||
} else {
|
||||
router.push(selectedModule.path)
|
||||
console.log('onModuleCommand setSendColumnsChildren3', selectedModule.path)
|
||||
mittBus.emit('setSendColumnsChildren', { children: [] })
|
||||
}
|
||||
|
||||
// 更新水平菜单和经典布局下的左侧菜单
|
||||
mittBus.emit('getBreadcrumbIndexSetFilterRoutes')
|
||||
if (themeConfig.value.layout === 'classic' && themeConfig.value.isClassicSplitMenu) {
|
||||
mittBus.emit('setSendClassicChildren', setSendClassicChildren(path))
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:计算二级菜单列表
|
||||
@ -239,14 +231,17 @@ const setSendSubMenuChildren = (path: string) => {
|
||||
res.children = sub.children ? [...sub.children] : []
|
||||
}
|
||||
}
|
||||
|
||||
console.log('res', res)
|
||||
return res
|
||||
}
|
||||
|
||||
// 新增:二级菜单点击处理
|
||||
const onSubMenuClick = (path: string) => {
|
||||
// 跳转到选中的二级路由
|
||||
router.push(path)
|
||||
// 更新左侧菜单
|
||||
mittBus.emit('getBreadcrumbIndexSetFilterRoutes')
|
||||
// 只更新左侧菜单为对应的三级菜单
|
||||
console.log('onSubMenuClick setSendColumnsChildren4', path)
|
||||
mittBus.emit('setSendColumnsChildren', setSendSubMenuChildren(path))
|
||||
}
|
||||
|
||||
@ -287,12 +282,11 @@ onBeforeRouteUpdate((to) => {
|
||||
if (matchedModule) {
|
||||
state.currentModulePath = matchedModule.path
|
||||
}
|
||||
|
||||
// 修复经典布局开启切割菜单时,点击tagsView后左侧导航菜单数据不变的问题
|
||||
let { layout, isClassicSplitMenu } = themeConfig.value
|
||||
if (layout === 'classic' && isClassicSplitMenu) {
|
||||
mittBus.emit('setSendClassicChildren', setSendClassicChildren(to.path))
|
||||
}
|
||||
// // 修复经典布局开启切割菜单时,点击tagsView后左侧导航菜单数据不变的问题
|
||||
// let { layout, isClassicSplitMenu } = themeConfig.value
|
||||
// if (layout === 'classic' && isClassicSplitMenu) {
|
||||
// mittBus.emit('setSendClassicChildren', setSendClassicChildren(to.path))
|
||||
// }
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -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) }}</span>
|
||||
<span>{{ $t(val.meta.title) + '12345' }}</span>
|
||||
</template>
|
||||
<sub-item :chil="val.children" />
|
||||
</el-sub-menu>
|
||||
@ -11,13 +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) }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a class="w100" @click.prevent="onALinkClick(val)">
|
||||
<SvgIcon :name="val.meta.icon" />
|
||||
{{ $t(val.meta.title) }}
|
||||
</a>
|
||||
<span>{{ $t(val.meta.title) + '123456' }}</span>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
@ -27,7 +21,6 @@
|
||||
<script setup lang="ts" name="navMenuSubItem">
|
||||
import { computed } from 'vue'
|
||||
import { RouteRecordRaw } from 'vue-router'
|
||||
import other from '/@/utils/other'
|
||||
|
||||
// 定义父组件传过来的值
|
||||
const props = defineProps({
|
||||
@ -40,10 +33,7 @@ const props = defineProps({
|
||||
|
||||
// 获取父级菜单数据
|
||||
const chils = computed(() => {
|
||||
console.log('chils', props.chil)
|
||||
return <RouteItems>props.chil
|
||||
})
|
||||
// 打开外部链接
|
||||
const onALinkClick = (val: RouteItem) => {
|
||||
other.handleOpenLink(val)
|
||||
}
|
||||
</script>
|
||||
|
@ -10,19 +10,24 @@
|
||||
<template v-for="val in menuLists">
|
||||
<el-sub-menu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
|
||||
<template #title>
|
||||
<SvgIcon :name="val.meta.icon" />
|
||||
<span>{{ $t(val.meta.title) }}</span>
|
||||
<SvgIcon :name="val.meta?.icon || ''" />
|
||||
<span>{{ $t(val.meta?.title || '') }}</span>
|
||||
</template>
|
||||
<SubItem :chil="val.children" />
|
||||
</el-sub-menu>
|
||||
<template v-else>
|
||||
<el-menu-item :index="val.path" :key="val.path">
|
||||
<SvgIcon :name="val.meta.icon" />
|
||||
<template #title v-if="!val.meta.isLink || (val.meta.isLink && val.meta.isIframe)">
|
||||
<span>{{ $t(val.meta.title) }}</span>
|
||||
<SvgIcon :name="val.meta?.icon || ''" />
|
||||
<template
|
||||
#title
|
||||
v-if="!val.meta?.isLink || (val.meta?.isLink && val.meta?.isIframe)"
|
||||
>
|
||||
<span>{{ $t(val.meta?.title || '') }}</span>
|
||||
</template>
|
||||
<template #title v-else>
|
||||
<a class="w100" @click.prevent="onALinkClick(val)">{{ $t(val.meta.title) }}</a>
|
||||
<a class="w100" @click.prevent="onALinkClick(val)">
|
||||
{{ $t(val.meta?.title || '') }}
|
||||
</a>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
@ -31,11 +36,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="navMenuVertical">
|
||||
import { defineAsyncComponent, reactive, computed, onMounted, watch } from 'vue'
|
||||
import { defineAsyncComponent, reactive, computed, ref, watch, onMounted } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import { useRoute, onBeforeRouteUpdate, RouteRecordRaw } from 'vue-router'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useThemeConfig } from '/@/stores/themeConfig'
|
||||
import other from '/@/utils/other'
|
||||
import mittBus from '/@/utils/mitt'
|
||||
|
||||
// 引入组件
|
||||
const SubItem = defineAsyncComponent(() => import('/@/layout/navMenu/subItem.vue'))
|
||||
@ -44,7 +51,7 @@ const SubItem = defineAsyncComponent(() => import('/@/layout/navMenu/subItem.vue
|
||||
const props = defineProps({
|
||||
// 菜单列表
|
||||
menuList: {
|
||||
type: Array<RouteRecordRaw>,
|
||||
type: Array as PropType<RouteItem[]>,
|
||||
default: () => [],
|
||||
},
|
||||
})
|
||||
@ -58,16 +65,42 @@ const state = reactive({
|
||||
isCollapse: false,
|
||||
})
|
||||
|
||||
// 获取父级菜单数据
|
||||
const menuLists = computed(() => {
|
||||
return <RouteItems>props.menuList
|
||||
// 本地菜单列表,用于响应水平菜单传递的菜单数据
|
||||
const localMenuList = ref<RouteItem[]>([])
|
||||
|
||||
// 初始化本地菜单
|
||||
localMenuList.value = props.menuList
|
||||
// Debug: initial menuList received
|
||||
console.log('vertical initial menuList:', props.menuList)
|
||||
|
||||
// 监听父组件传入的 menuList
|
||||
watch(
|
||||
() => props.menuList,
|
||||
(newList) => {
|
||||
// Debug: props.menuList changed
|
||||
console.log('vertical props.menuList changed:', newList)
|
||||
localMenuList.value = newList
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
// 订阅水平菜单发送的菜单数据
|
||||
mittBus.on('setSendColumnsChildren', (res) => {
|
||||
// Debug: received setSendColumnsChildren event
|
||||
console.log('vertical received setSendColumnsChildren:', res)
|
||||
localMenuList.value = res.children || []
|
||||
})
|
||||
|
||||
// 获取父级菜单数据
|
||||
const menuLists = computed(() => localMenuList.value)
|
||||
// 获取布局配置信息
|
||||
const getThemeConfig = computed(() => {
|
||||
return themeConfig.value
|
||||
})
|
||||
// 菜单高亮(详情时,父级高亮)
|
||||
const setParentHighlight = (currentRoute: RouteToFrom) => {
|
||||
console.log('vertical currentRoute', currentRoute)
|
||||
|
||||
const { path, meta } = currentRoute
|
||||
const pathSplit = meta?.isDynamic ? meta.isDynamicPath!.split('/') : path!.split('/')
|
||||
if (pathSplit.length >= 4 && meta?.isHide) return pathSplit.splice(0, 3).join('/')
|
||||
@ -79,10 +112,14 @@ const onALinkClick = (val: RouteItem) => {
|
||||
}
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
// Debug: onMounted, current route
|
||||
console.log('vertical onMounted route.path:', route.path)
|
||||
state.defaultActive = setParentHighlight(route)
|
||||
})
|
||||
// 路由更新时
|
||||
onBeforeRouteUpdate((to) => {
|
||||
// Debug: onBeforeRouteUpdate, target route
|
||||
console.log('vertical onBeforeRouteUpdate to.path:', to.path)
|
||||
state.defaultActive = setParentHighlight(to)
|
||||
const clientWidth = document.body.clientWidth
|
||||
if (clientWidth < 1000) themeConfig.value.isCollapse = false
|
||||
|
Loading…
x
Reference in New Issue
Block a user