在 Vue.js 中,使用 Vue Router 管理路由数据,并将其用于渲染 el-menu(Element UI 的菜单组件)通常涉及以下几个步骤:
-  定义路由元数据: 
 在你的路由配置中,为每个路由项添加meta字段,这个字段可以包含任何你想要传递给菜单的数据,例如菜单名称、图标等。
-  获取路由数据: 
 使用router实例的getRoutes()方法来获取当前注册的所有路由信息。
-  过滤和格式化数据: 
 根据需要过滤和格式化路由数据,以便它们可以被el-menu组件使用。
-  将数据传递给组件: 
 将格式化好的路由数据传递给使用el-menu的组件。
-  使用 v-for 渲染菜单: 
 在组件的模板中,使用v-for指令来遍历路由数据,并渲染el-menu。
实现效果

路由配置
首先是路由配置,要实现这个路由配置,你需要完成以下几个步骤:
-  注册 Vue Router:确保你已经在你的 Vue 应用中安装并注册了 Vue Router。 
-  定义路由:使用 Vue Router 的 addRoute方法动态添加路由。
-  使用路由:在应用中使用 <router-view>来渲染对应的组件。
-  渲染菜单:如果你需要根据路由配置动态渲染菜单(例如使用 Element UI 的 el-menu),你需要从路由配置中提取必要的信息。
下面是一个基本的实现示例:
main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // 假设你有一个 router 文件const app = createApp(App);app.use(router).mount('#app');
router.js
import { createRouter, createWebHistory } from 'vue-router';
import Main from '../views/Main.vue';
import Home from '../views/Home.vue';
import Goods from '../views/goods.vue';
import Order from '../views/order.vue';const routes = [{path: '/',name: 'main',component: Main,children: [{path: 'home',name: 'home',component: Home,meta: { title: '主页', icon: 'house' },},{path: 'goods',name: 'Goods',component: Goods,meta: { title: '商品列表', icon: 'el-icon-shopping-cart-full' },},{path: 'order',name: 'Order',redirect: 'order/table',children: [{path: 'table',name: 'Table',component: Order,meta: { title: '订单列表', icon: 'el-icon-s-fold' },},],meta: { title: '订单', icon: 'el-icon-s-claim' },},],},
];const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes,
});export default router;
App.vue
<template><div id="app"><router-view></router-view></div>
</template><script>
export default {name: 'App',
};
</script>
动态渲染菜单
如果你想根据路由配置动态渲染菜单(el-menu),你可以在组件中使用 Vue Router 的 routes 属性。以下是一个使用组合式 API 的示例:
MenuComponent.vue
<template><el-aside :width="width"><el-menubackground-color="#fff"active-text-color="#409eff"class="aside-menu":collapse="isCollapse":default-active="activeMenu"><el-menu-item v-for="item in noChilden":index="item.path":key="item.path"@click="handlemenu(item)"><component class="icon" :is="item.meta.icon"></component><span>{{ item.meta.title }}</span>        </el-menu-item><el-sub-menu v-for="item in hasChilden":index="item.path":key="item.path"><template #title><component class="icon" :is="item.meta.icon"></component><span>{{ item.meta.title }}</span></template><!-- <el-menu-item-group> --><el-menu-item v-for="subItem in item.children":key="subItem.path":index="subItem.path"@click="handlemenuchild(item,subItem)"class="sub-menu-deep"><component class="icon" :is="subItem.meta.icon"></component><span>{{ subItem.meta.title }}</span></el-menu-item><!-- </el-menu-item-group> --></el-sub-menu></el-menu></el-aside>
</template><script setup>import {ref,computed,onMounted} from 'vue'
import {useAllDataStore} from "@/store"
import {useRouter,useRoute} from 'vue-router'const list = ref([]);
const router = useRouter();
onMounted(() =>{
//找到根路由
const childRoutes = router.getRoutes().find(route => route.path === '/').children; list.value = childRoutes.filter(route => route.meta && route.meta.title);
console.log(list.value);
});
const hasChilden = computed(() => list.value.filter(item => item.children && item.children.length > 0))
const noChilden = computed(() => list.value.filter(item => !item.children || item.children.length === 0))const route = useRoute()
const handlemenu = (item) =>{router.push(item.path)}
const handlemenuchild = (item,subItem) =>{router.push(item.path+'/'+ subItem.path)
}
const activeMenu = computed(() => route.path)
</script><style lang="less" scoped>
.icon{width:18px;height: 18px;margin-right: 5px;
}
.el-menu {border-right: none;font-size: 20px;font-weight: bold;h3{line-height: 48px;text-align: center;}
}
.el-aside{height:100%;background-color: #fff;// box-shadow: 1px 0px 5px rgba(0, 0, 0, 0.2);border-right: 1px solid #e4e7ed;
}</style>解释上面是怎么实现router 动态渲染菜单的
这段代码是一个使用 Vue 3 和 Element UI 库实现的侧边导航菜单组件,它通过 Vue Router 的路由信息动态渲染菜单项。下面是代码的详细解释:
布局中引入组件
<script setup>
import CommonAside from '@/components/.vue'
import CommonHeader from '../components/MenuComponent.vue';
import CommonTab from '@/components/CommonTab.vue'
</script><template><div class="common-layput"><el-container class="lay-container"><!-- 自定义左侧菜单组件 --><menu-component /><el-container><el-header class="el-header"><common-header /></el-header><el-main class="right-mian"><!-- 路由显示内容 --><router-view></router-view></el-main></el-container></el-container></div>
</template><style scoped lang="less">.common-layput,.lay-container{height:100%;}.el-header{background-color: #fff;box-shadow: 1px 0px 5px rgba(0, 0, 0, 0.2);}
</style>
模板部分 (<template>)
 
- 使用 el-aside组件作为侧边栏容器。
- el-menu组件用于创建菜单,其中:- background-color和- active-text-color设置菜单的背景色和激活项的文字颜色。
- class添加自定义类名。
- :collapse属性用于控制菜单的展开和收起状态。
- :default-active绑定当前激活的菜单项路径。
 
菜单项和子菜单项渲染
- 使用 el-menu-item组件渲染没有子菜单的顶级菜单项。
- 使用 el-sub-menu组件渲染带有子菜单的菜单项。
脚本部分 (<script setup>)
 
- 引入必要的 Vue 组合式 API 钩子:ref,computed,onMounted,useRouter,useRoute。
- list引用用于存储从 Vue Router 获取的路由信息。
路由信息获取
- 在 onMounted钩子中,使用useRouter钩子的getRoutes方法找到根路由'/'的子路由,并筛选出包含meta和meta.title的路由,存储到list.value。
计算属性
- hasChilden:计算属性,筛选出- list.value中具有子菜单的路由。
- noChilden:计算属性,筛选出- list.value中没有子菜单的路由。
导航处理函数
- handlemenu:处理无子菜单项的点击事件,使用- router.push方法导航到点击的菜单项路径。
- handlemenuchild:处理有子菜单项的点击事件,拼接父菜单和子菜单的路径,然后导航。
激活状态
- activeMenu:计算属性,根据当前路由的路径- route.path设置激活的菜单项。
样式部分 (<style>)
 
- 定义了一些基本的样式来美化菜单,例如移除边框、设置字体大小和加粗。
总结
这个组件通过 Vue Router 的 useRouter 钩子获取当前路由的配置信息,并根据这些信息动态生成菜单项。使用 computed 属性来区分哪些路由有子菜单,哪些没有,然后相应地渲染 el-menu-item 或 el-sub-menu。点击菜单项时,使用 router.push 方法来改变页面的路由,实现导航功能。并通过 useRoute 钩子获取当前激活的路由,然后设置 activeMenu 来决定哪个菜单项应该处于激活状态。这个组件是一个结合 Vue Router 和 Element UI 的动态菜单实现,它可以自动根据路由配置渲染出相应的菜单结构,并且能够响应路由变化,高亮显示当前激活的菜单项。