<template>
|
<div v-if="!isItemHidden" class="root-sidebar-item">
|
<template
|
v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !(item.meta && item.meta.alwaysShow)"
|
>
|
<app-link class="link" :to="resolvePath(onlyOneChild.path)">
|
<el-menu-item
|
class="left-menu-item"
|
v-if="onlyOneChild.meta"
|
:index="resolvePath(onlyOneChild.path)"
|
:class="{ 'submenu-title-noDropdown': !isNest }"
|
>
|
<!-- <item :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" :title="onlyOneChild.meta.title" /> -->
|
<template v-if="get2MetaIconPath(onlyOneChild, item)">
|
<template
|
v-if="typeof get2MetaIconPath(onlyOneChild, item) === 'string'"
|
>
|
<svg-icon :icon-class="get2MetaIconPath(onlyOneChild, item)" />
|
<span
|
v-if="secondMenuPopup && isTopRoute"
|
class="text text-one text-one-added"
|
>{{ onlyOneChild.meta.title
|
}}</span
|
>
|
</template>
|
<component
|
v-else
|
:is="get2MetaIconPath(onlyOneChild, item)"
|
class="svg-icon el-svg-icon"
|
/>
|
</template>
|
<template #title>
|
<span class="text text-one">{{ onlyOneChild.meta.title }}</span>
|
</template>
|
</el-menu-item>
|
</app-link>
|
</template>
|
|
<el-sub-menu
|
class="left-sub-menu"
|
v-else
|
ref="subMenu"
|
:index="resolvePath(item.path)"
|
teleported
|
>
|
<template v-if="item.meta" #title>
|
<!-- <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> -->
|
<template v-if="getMetaIconPath(item)">
|
<svg-icon
|
v-if="typeof getMetaIconPath(item) === 'string'"
|
:icon-class="getMetaIconPath(item)"
|
/>
|
<component
|
v-else
|
:is="getMetaIconPath(item)"
|
class="svg-icon el-svg-icon"
|
/>
|
</template>
|
<!-- <svg-icon v-else icon-class="list" /> -->
|
<span class="text text-two">{{ 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 name="SidebarItem">
|
import { ref, computed, } from 'vue';
|
import path from 'path-browserify';
|
import { isExternal } from '@/utils/validate';
|
// import Item from './Item';
|
import AppLink from './Link';
|
import { storeToRefs } from 'pinia';
|
import { useSettingsStore } from '@/store/settings';
|
const settingsStore = useSettingsStore();
|
const { secondMenuPopup } = storeToRefs(settingsStore);
|
|
const onlyOneChild = ref(null);
|
const props = defineProps({
|
item: {
|
type: Object,
|
required: true
|
},
|
basePath: {
|
type: String,
|
default: ''
|
},
|
isNest: {
|
type: Boolean,
|
default: false
|
},
|
isTopRoute: { // 是否为顶层路由
|
type: Boolean,
|
default: false
|
}
|
});
|
|
const isItemHidden = computed(() => {
|
if (props.item.meta && props.item.meta.hidden) {
|
return true;
|
}
|
return false;
|
});
|
|
function getMetaIconPath(_item) {
|
return _item.meta && _item.meta.icon;
|
}
|
|
function get2MetaIconPath(_onlyOneChild, _item) {
|
return _onlyOneChild.meta.icon || (_item.meta && _item.meta.icon);
|
}
|
|
function hasOneShowingChild(children = [], parent) {
|
const showingChildren = children.filter((_item) => {
|
if (isItemHidden.value) {
|
return false;
|
} else {
|
// Temp set(will be used if only has one showing child)
|
onlyOneChild.value = _item;
|
return true;
|
}
|
});
|
|
if (showingChildren.length === 1) {
|
return true;
|
}
|
|
if (showingChildren.length === 0) {
|
onlyOneChild.value = { ...parent, path: '', noShowingChildren: true };
|
return true;
|
}
|
|
return false;
|
}
|
|
function resolvePath(routePath) {
|
if (isExternal(routePath)) {
|
return routePath;
|
}
|
if (isExternal(props.basePath)) {
|
return props.basePath;
|
}
|
return path.resolve(props.basePath, routePath);
|
}
|
</script>
|
|
<style lang="less" scoped>
|
.link :deep(.el-menu-tooltip__trigger) {
|
position: relative;
|
padding: 0;
|
}
|
|
.left-menu-item,
|
.left-sub-menu :deep(.el-sub-menu__title) {
|
display: block;
|
}
|
|
.el-svg-icon {
|
width: 1em;
|
height: 1em;
|
vertical-align: -0.15em;
|
fill: currentColor;
|
overflow: hidden;
|
}
|
</style>
|