AppMenuTree.vue 1.28 KB
<template>
  <template v-for="menu in menus" :key="menu.code">
    <a-sub-menu v-if="menu.children?.length" :key="menu.code">
      <template #icon>
        <component :is="resolveIcon(menu.icon)" v-if="resolveIcon(menu.icon)" />
      </template>
      <template #title>{{ menu.name }}</template>
      <AppMenuTree :menus="menu.children" />
    </a-sub-menu>
    <a-menu-item v-else :key="menu.path || menu.code">
      <template #icon>
        <component :is="resolveIcon(menu.icon)" v-if="resolveIcon(menu.icon)" />
      </template>
      {{ menu.name }}
    </a-menu-item>
  </template>
</template>

<script setup lang="ts">
import type { Component } from 'vue'
import type { MenuNode } from '@/types/auth'
import {
  ApiOutlined,
  ApartmentOutlined,
  ControlOutlined,
  GlobalOutlined,
  HomeOutlined,
  ShopOutlined,
  StarOutlined,
  UnorderedListOutlined,
  UserOutlined,
} from '@ant-design/icons-vue'

withDefaults(defineProps<{ menus: MenuNode[] }>(), {
  menus: () => [],
})

const iconMap: Record<string, Component> = {
  HomeOutlined,
  GlobalOutlined,
  ApartmentOutlined,
  ShopOutlined,
  UserOutlined,
  StarOutlined,
  UnorderedListOutlined,
  ControlOutlined,
  ApiOutlined,
}

function resolveIcon(icon?: string) {
  if (!icon) return null
  return iconMap[icon] || null
}
</script>