Files
vue3-element-admin/src/layout/components/Sidebar/SidebarItem.vue
郝先瑞 12c78f96d7 refactor: ♻️ 项目重构(临时提交)
Former-commit-id: 14e64324f7556c095c38ad289690367cdac0ec56
2023-11-16 22:46:28 +08:00

139 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import path from "path-browserify";
import { isExternal } from "@/utils/index";
import AppLink from "./Link.vue";
import { RouteRecordRaw } from "vue-router";
import Item from "./Item.vue";
const props = defineProps({
/**
* 路由(eg:user)
*/
item: {
type: Object,
required: true,
},
/**
* 父层级完整路由路径(eg:/system)
*/
basePath: {
type: String,
required: true,
},
isNest: {
type: Boolean,
default: false,
},
});
const onlyOneChild = ref(); // 临时变量,唯一子路由
/**
* 判断当前路由是否只有一个子路由
*
* 1如果只有一个子路由 返回 true
* 2如果无子路由 :返回 true
*
* @param children 子路由数组
* @param parent 当前路由
*/
function hasOneShowingChild(
children: RouteRecordRaw[] = [],
parent: RouteRecordRaw
) {
// 子路由集合
const showingChildren = children.filter((route: RouteRecordRaw) => {
if (route.meta?.hidden) {
// 过滤不显示的子路由
return false;
} else {
route.meta!.hidden = false;
// 临时变量(多个子路由 onlyOneChild 变量是用不上的)
onlyOneChild.value = route;
return true;
}
});
// 如果只有一个子路由, 返回 true
if (showingChildren.length === 1) {
return true;
}
// 如果没有子路由,显示父级路由
if (showingChildren.length === 0) {
onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
return true;
}
return false;
}
/**
* 解析路由路径(相对路径 → 绝对路径)
*
* @param routePath 路由路径
*/
function resolvePath(routePath: string) {
if (isExternal(routePath)) {
return routePath;
}
if (isExternal(props.basePath)) {
return props.basePath;
}
// 完整路径(/system/user) = 父级路径(/system) + 路由路径(user)
const fullPath = path.resolve(props.basePath, routePath);
return fullPath;
}
</script>
<template>
<div v-if="!item.meta || !item.meta.hidden">
<!-- 无子路由 || 目录只有一个子路由并配置始终显示为否(alwaysShow=false) -->
<template
v-if="
hasOneShowingChild(item.children, item as RouteRecordRaw) &&
(!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
!item.meta?.alwaysShow
"
>
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item
:index="resolvePath(onlyOneChild.path)"
:class="{ 'submenu-title-noDropdown': !isNest }"
>
<item
:icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"
:title="onlyOneChild.meta.title"
/>
</el-menu-item>
</app-link>
</template>
<!-- 有子路由 -->
<el-sub-menu v-else :index="resolvePath(item.path)" teleported>
<template #title>
<item
v-if="item.meta"
:icon="item.meta && item.meta.icon"
:title="item.meta.title"
/>
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
/>
</el-sub-menu>
</div>
</template>
<style lang="scss" scoped>
:deep(.el-menu-item .el-menu-tooltip__trigger) {
width: auto !important;
}
</style>