大致流程:把接口返回的目录格式化为route结构,然后在tsx文件返回menu目录在vue文件中显示。
接口返回的目录格式化为route结构不做叙述,大概有这些

[{
    path: '/tenantManage',
    name: 'TenantManage',
    component: () => import('@/views/system/tenantManage/index.vue'),
    meta: {
        title: '租户管理',
        breadcrumb: true
    },
    children: [
        {
            path: '/initialization',
            name: 'TenantInitialization',
            hidden: false,
            component: () => import('@/views/system/tenantManage/initialization.vue'),
            meta: {
                title: '租户初始化',
                breadcrumb: true
            }
        }
    ]
},{
    path: '/serverManage',
    name: 'ServerManage',
    component: () => import('@/views/system/serverManage/index.vue'),
    meta: {
        title: '服务管理',
        breadcrumb: true
    }
}]

重点是tsx文件
由于tsx不能直接写css,所以要导入css文件
导入router,遍历对于有children并且至少有一个children是展示的就展示el-sub-menu,否则就是el-menu-item,最终导出,完整代码

import './subMenu.css'
import { compact, map } from 'lodash'
import type { ExtendedRouteRecordRaw } from '@/@types/router'
import { customerRoutes } from '@/router/routes'
import router from '@/router'

const renderItem = (item: ExtendedRouteRecordRaw) => {
    return (
        <el-menu-item class="side-menu-item"  index={item.name} onClick={() => router.push(item.path)} >
            <el-icon><document /></el-icon>
            {item.meta?.title}
        </el-menu-item>
    )
}
const readerMenu = (route: ExtendedRouteRecordRaw[], parentKey?: string) => {
    return (
        compact(map(route, ((item, index) => {
            if (item.hidden) return null
            const key = parentKey ? `${parentKey}-${index}` : `${index}`
            if (item.children) {
                const childrenAllHiden = item.children.every((child: ExtendedRouteRecordRaw) => child.hidden)
                return (childrenAllHiden ? renderItem(item) :
                    (
                        <el-sub-menu class="side-menu-item" index={`submenu-${key}`} v-slots={{
                            title: () => [
                            // 根据接口返回替换el-icon或不用
                                <el-icon><location /></el-icon>,
                                <p>{item.meta?.title}</p>
                            ]
                        }}>
                            {readerMenu(item.children, key)}
                        </el-sub-menu>
                    )
                )
            } else {
                return renderItem(item)
            }
        })))
    )
}

export default {
    render() {
        return (
             readerMenu(customerRoutes)
        )
    }
}

在vue文件中引入

<template>
    <div class='sider-container'>
        <div class='sider-logo'>
            <div class="sider-avatar"></div>
            <span class='ml-xs text-2xl font-medium'>权限配置</span>
        </div>
        <el-menu>
            <SystemSider />
        </el-menu>
    </div>
</template>
<script setup lang='ts'>
import SystemSider from './subMenu.tsx'
</script>

更多推荐