递归组件生成动态菜单

路由数据自定义

    routes: [
        {
            path: '/',
            //@ts-ignore 
            component: () => import('../views/layout/index.vue'),
            name: 'layout',
            meta: {
                name: 'layout', //路由标题
                hidden: true, //是否显示 true表示显示 fasle表示隐藏
            },
            children: [
                {
                    path: '/home',
                    //@ts-ignore  
                    component: () => import('../views/layout/home/index.vue'),
                    name: 'home',
                    meta: { name: '首页' }
                },
                {
                    path: '/yhgl',
                    //@ts-ignore  解决引入问题
                    component: () => import('../views/layout/yhgl/index.vue'),
                    name: '/yhgl',
                    meta: { name: '用户管理' }
                },
                {
                    path: '/wd',
                    //@ts-ignore 
                    component: () => import('../views/layout/wd/index.vue'),
                    name: 'wd',
                    meta: { name: '问答' }
                }, {
                    path: '/gg',
                    //@ts-ignore 
                    component: () => import('../views/layout/gg/index.vue'),
                    name: 'gg',
                    meta: { name: '公告' }
                },
            ]
        },
        {
            path: '/login',
            //@ts-ignore 
            component: () => import('../views/login/index.vue'),
            name: 'login',
            meta: {
                name: '登录',
                hidden: true, //是否显示 true表示显示 fasle表示隐藏 
            }
        }

    ],

获取到所有的路由数据

//获取项目中所有的路由
import router from '../../router/index'
const AllRouter = ref(router.options.routes)
console.log(AllRouter.value);

 封装菜单组件  采用element ui 


<script setup lang="ts">

defineProps(['routers']) //接收传递过来的路由参数



</script>
<script lang="ts">
export default {  //需要使用自身组件必须定义name
    name: 'Menu'
}
</script>

<template>
    <div class="menu">
        <!-- 使用templete模板遍历所有路由 -->
        <template v-for="(router) in routers" :key="router.path">
            <!-- 展示一级路由  没有children-->
            <template v-if="!router.children">
                <el-menu-item :index="router.path" v-if="router.meta.hidden"> <!-- 判断是否显示该路由 -->
                    <span>{{ router.meta?.name }}</span>
                </el-menu-item>
            </template>
            <!-- 有children但是只有一个子选项也使用一级菜单展示 -->
            <template v-if="router.children && router.children.length == 1">
                <el-menu-item :index="router.children[0].path" v-if="router.children[0].meta.hidden"> <!-- 判断是否显示该路由 -->
                    <span> {{ router.children[0].meta?.name }} {{ router.children[0].path }}</span>
                </el-menu-item>
            </template>

            <!-- 多级菜单 -->
            <el-sub-menu :index="router.path" v-if="router.children && router.children.length > 1">
                <template #title>
                    <span>{{ router.meta?.name }}</span>
                </template>
                <!-- 因为children有可能还存在嵌套children 所以采用递归组件 -->
                <Menu :routers="router.children"></Menu>
            </el-sub-menu>
        </template>
    </div>
</template>

<style lang="scss" scoped>
.menu {
    width: 100%;
    height: 100%;
}
</style>

需要使用menu的页面使用

<script setup lang="ts">
import { ref } from 'vue'
//引入menu组件
import Menu from './menu/index.vue'
//获取项目中所有的路由
import router from '../../router/index'
const AllRouter = ref(router.options.routes)
console.log(AllRouter.value);


</script>

<template>
  <div class="layout">
    <!-- 主体布局 -->
    <div class="common-layout">
      <el-container>
        <!-- 左侧菜单 -->
        <el-aside width="200px">
           <!-- 使用menu组件并传递数据 -->
          <el-menu active-text-color="#ffd04b" background-color="#545c64"
            text-color="#fff" router >
            <Menu :routers="AllRouter"></Menu>
          </el-menu>
        </el-aside>
        <el-container>
          <!-- 头部 -->
          <el-header>Header</el-header>
          <!-- 内容 -->
          <el-main>
            <router-view></router-view>
          </el-main>
        </el-container>
      </el-container>
    </div>

  </div>
</template>

<style lang="scss" scoped>
.layout {
  width: 100%;
  height: 100vh;

  .el-aside {
    height: 100vh;
    background-color: rgb(84, 92, 100);

    .el-menu{ //去掉menu右侧的边框
      border-right: none;
    }
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值