<template>
|
<!-- <div v-if="!item.hidden">-->
|
<!-- <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">-->
|
<!-- <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">-->
|
<!-- <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">-->
|
<!-- <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>-->
|
<!-- <template #title><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span></template>-->
|
<!-- </el-menu-item>-->
|
<!-- </app-link>-->
|
<!-- </template>-->
|
|
<!-- <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>-->
|
<!-- <template v-if="item.meta" #title>-->
|
<!-- <svg-icon :icon-class="item.meta && item.meta.icon" />-->
|
<!-- <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>-->
|
<!-- </template>-->
|
|
<!-- <sidebar-item-->
|
<!-- v-for="child in item.children"-->
|
<!-- :key="child.path"-->
|
<!-- :is-nest="true"-->
|
<!-- :item="child"-->
|
<!-- :base-path="resolvePath(child.path)"-->
|
<!-- class="nest-menu"-->
|
<!-- />-->
|
<!-- </el-sub-menu>-->
|
<!-- </div>-->
|
<div v-if="!item.hidden">
|
<!-- 优化条件:优先判定【仅有1个可见子菜单】,直接走一级菜单渲染 -->
|
<template v-if="calcSingleChild(item) && item.path != '/system'">
|
<app-link v-if="onlyOneChild?.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
|
<el-menu-item
|
:index="resolvePath(onlyOneChild.path)"
|
:class="{ 'submenu-title-noDropdown': !isNest }"
|
>
|
<svg-icon :icon-class="item.meta?.icon || onlyOneChild.meta?.icon"/>
|
<template #title>
|
<span class="menu-title" :title="hasTitle(item.meta?.title || onlyOneChild.meta?.title)">
|
{{ item.meta?.title || onlyOneChild.meta?.title }}
|
</span>
|
</template>
|
</el-menu-item>
|
</app-link>
|
</template>
|
|
<!-- 多个子菜单 / 强制目录:正常展开二级菜单 -->
|
<el-sub-menu
|
v-else
|
ref="subMenu"
|
:index="resolvePath(item.path)"
|
popper-append-to-body
|
>
|
<template v-if="item.meta" #title>
|
<svg-icon :icon-class="item.meta && item.meta.icon" />
|
<span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
|
</template>
|
|
<sidebar-item
|
v-for="child in item.children"
|
:key="child.path"
|
:is-nest="true"
|
:item="child"
|
:base-path="resolvePath(child.path)"
|
class="nest-menu"
|
/>
|
</el-sub-menu>
|
</div>
|
</template>
|
|
<!--<script setup>-->
|
<!--import { isExternal } from '@/utils/validate'-->
|
<!--import AppLink from './Link'-->
|
<!--import { getNormalPath } from '@/utils/ruoyi'-->
|
|
<!--const props = defineProps({-->
|
<!-- // route object-->
|
<!-- item: {-->
|
<!-- type: Object,-->
|
<!-- required: true-->
|
<!-- },-->
|
<!-- isNest: {-->
|
<!-- type: Boolean,-->
|
<!-- default: false-->
|
<!-- },-->
|
<!-- basePath: {-->
|
<!-- type: String,-->
|
<!-- default: ''-->
|
<!-- }-->
|
<!--})-->
|
|
<!--const onlyOneChild = ref({});-->
|
|
<!--function hasOneShowingChild(children = [], parent) {-->
|
<!-- if (!children) {-->
|
<!-- children = [];-->
|
<!-- }-->
|
<!-- const showingChildren = children.filter(item => {-->
|
<!-- if (item.hidden) {-->
|
<!-- return false-->
|
<!-- } else {-->
|
<!-- // Temp set(will be used if only has one showing child)-->
|
<!-- onlyOneChild.value = item-->
|
<!-- return true-->
|
<!-- }-->
|
<!-- })-->
|
|
<!-- // When there is only one child router, the child router is displayed by default-->
|
<!-- if (showingChildren.length === 1) {-->
|
<!-- return true-->
|
<!-- }-->
|
|
<!-- // Show parent if there are no child router to display-->
|
<!-- if (showingChildren.length === 0) {-->
|
<!-- onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }-->
|
<!-- return true-->
|
<!-- }-->
|
|
<!-- return false-->
|
<!--};-->
|
|
<!--function resolvePath(routePath, routeQuery) {-->
|
<!-- if (isExternal(routePath)) {-->
|
<!-- return routePath-->
|
<!-- }-->
|
<!-- if (isExternal(props.basePath)) {-->
|
<!-- return props.basePath-->
|
<!-- }-->
|
<!-- if (routeQuery) {-->
|
<!-- let query = JSON.parse(routeQuery);-->
|
<!-- return { path: getNormalPath(props.basePath + '/' + routePath), query: query }-->
|
<!-- }-->
|
<!-- return getNormalPath(props.basePath + '/' + routePath)-->
|
<!--}-->
|
|
<!--function hasTitle(title){-->
|
<!-- if (title.length > 5) {-->
|
<!-- return title;-->
|
<!-- } else {-->
|
<!-- return "";-->
|
<!-- }-->
|
<!--}-->
|
<!--</script>-->
|
<script setup>
|
import { ref } from 'vue'
|
import { isExternal } from '@/utils/validate'
|
import AppLink from './Link'
|
import { getNormalPath } from '@/utils/ruoyi'
|
|
const props = defineProps({
|
// route object
|
item: {
|
type: Object,
|
required: true
|
},
|
isNest: {
|
type: Boolean,
|
default: false
|
},
|
basePath: {
|
type: String,
|
default: ''
|
}
|
})
|
|
// 修复:初始化为 null,而非空对象
|
const onlyOneChild = ref(null);
|
|
/**
|
* 修复版:判断是否只有一个可见子菜单(核心改动)
|
*/
|
function hasOneShowingChild(children = [], parent) {
|
if (!children) children = []
|
|
// 1. 先统一过滤出【未隐藏】的子菜单
|
const showingChildren = children.filter(item => !item.hidden)
|
|
// 2. 仅有 1 个可见子菜单:赋值 + 标记无下级,适配原有判断
|
if (showingChildren.length === 1) {
|
const child = showingChildren[0]
|
// 标记:当前子菜单没有可展示的下级(关键,适配原模板逻辑)
|
onlyOneChild.value = { ...child, noShowingChildren: true }
|
return true
|
}
|
|
// 3. 没有可见子菜单
|
if (showingChildren.length === 0) {
|
onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
|
return true
|
}
|
|
// 4. 多个子菜单
|
onlyOneChild.value = null
|
return false
|
}
|
|
/**
|
* 新增统一判断方法:简化模板条件,命中「单菜单合并逻辑」
|
*/
|
function calcSingleChild(item) {
|
// 存在子菜单 且 仅有一个可见子菜单
|
return hasOneShowingChild(item.children, item)
|
}
|
|
function resolvePath(routePath, routeQuery) {
|
if (isExternal(routePath)) {
|
return routePath
|
}
|
if (isExternal(props.basePath)) {
|
return props.basePath
|
}
|
if (routeQuery) {
|
let query = JSON.parse(routeQuery);
|
return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
|
}
|
return getNormalPath(props.basePath + '/' + routePath)
|
}
|
|
function hasTitle(title){
|
if (title && title.length > 5) {
|
return title;
|
} else {
|
return "";
|
}
|
}
|
</script>
|