| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- <script setup>
- import { computed } from "vue"
- import SidebarItemLink from "./SidebarItemLink.vue"
- import { isExternal } from "@/utils/validate"
- import path from "path-browserify"
- const props = defineProps({
- item: {
- type: Object,
- required: true
- },
- basePath: {
- type: String,
- default: ""
- }
- })
- /** 是否始终显示根菜单 */
- const alwaysShowRootMenu = computed(() => props.item.meta?.alwaysShow)
- /** 显示的子菜单 */
- const showingChildren = computed(() => {
- return props.item.children?.filter((child) => !child.meta?.hidden) ?? []
- })
- /** 显示的子菜单数量 */
- const showingChildNumber = computed(() => {
- return showingChildren.value.length
- })
- /** 唯一的子菜单项 */
- const theOnlyOneChild = computed(() => {
- const number = showingChildNumber.value
- switch (true) {
- case number > 1:
- return null
- case number === 1:
- return showingChildren.value[0]
- default:
- return { ...props.item, path: "" }
- }
- })
- /** 解析路径 */
- const resolvePath = (routePath) => {
- switch (true) {
- case isExternal(routePath):
- return routePath
- case isExternal(props.basePath):
- return props.basePath
- default:
- return path.resolve(props.basePath, routePath)
- }
- }
- </script>
- <template>
- <template v-if="!alwaysShowRootMenu && theOnlyOneChild && !theOnlyOneChild.children">
- <SidebarItemLink v-if="theOnlyOneChild.meta" :to="resolvePath(theOnlyOneChild.path)">
- <el-menu-item :index="resolvePath(theOnlyOneChild.path)">
- <SvgIcon v-if="theOnlyOneChild.meta.svgIcon" :name="theOnlyOneChild.meta.svgIcon" />
- <component v-else-if="theOnlyOneChild.meta.elIcon" :is="theOnlyOneChild.meta.elIcon" class="el-icon" />
- <template v-if="theOnlyOneChild.meta.title" #title>
- <span class="title">{{ theOnlyOneChild.meta.title }}</span>
- </template>
- </el-menu-item>
- </SidebarItemLink>
- </template>
- <el-sub-menu v-else :index="resolvePath(props.item.path)" teleported>
- <template #title>
- <SvgIcon v-if="props.item.meta?.svgIcon" :name="props.item.meta.svgIcon" />
- <component v-else-if="props.item.meta?.elIcon" :is="props.item.meta.elIcon" class="el-icon" />
- <span v-if="props.item.meta?.title" class="title">{{ props.item.meta.title }}</span>
- </template>
- <template v-if="props.item.children">
- <SidebarItem
- v-for="child in showingChildren"
- :key="child.path"
- :item="child"
- :base-path="resolvePath(child.path)"
- />
- </template>
- </el-sub-menu>
- </template>
- <style lang="scss" scoped>
- .svg-icon {
- min-width: 1em;
- margin-right: 30px;
- font-size: 20px;
- z-index: 1;
- }
- .el-icon {
- width: 1em !important;
- margin-right: 30px !important;
- font-size: 20px;
- z-index: 1;
- }
- .title {
- z-index: 1;
- }
- </style>
|