SidebarItem.vue 1.47 KB
<template>
  <div v-if="!(menu as any).meta?.hidden">
    <!-- 有子菜单的情况 -->
    <el-sub-menu
      v-if="hasChildren"
      :index="resolvePath"
      :popper-append-to-body="false"
    >
      <template #title>
        <el-icon v-if="menu.icon">
          <component :is="menu.icon" />
        </el-icon>
        <span>{{ menu.menuName }}</span>
      </template>
      
      <sidebar-item
        v-for="child in menu.children"
        :key="child.menuId"
        :menu="child"
        :base-path="resolvePath"
      />
    </el-sub-menu>
    
    <!-- 没有子菜单的情况 -->
    <el-menu-item
      v-else
      :index="resolvePath"
    >
      <el-icon v-if="menu.icon">
        <component :is="menu.icon" />
      </el-icon>
      <template #title>
        <span>{{ menu.menuName }}</span>
      </template>
    </el-menu-item>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import type { Menu } from '@/types'

interface Props {
  menu: Menu
  basePath: string
}

const props = defineProps<Props>()

// 是否有子菜单
const hasChildren = computed(() => {
  return props.menu.children && props.menu.children.length > 0
})

// 解析路径
const resolvePath = computed(() => {
  if (props.menu.path.startsWith('/')) {
    return props.menu.path
  }
  return `${props.basePath}/${props.menu.path}`
})
</script>

<style lang="scss" scoped>
.el-menu-item,
.el-sub-menu__title {
  .el-icon {
    margin-right: 8px;
    font-size: 16px;
  }
}
</style>