vue3+element-plus 实现动态菜单和动态路由的渲染的项目实践
作者:gt8011
在 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-menu background-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 的动态菜单实现,它可以自动根据路由配置渲染出相应的菜单结构,并且能够响应路由变化,高亮显示当前激活的菜单项。
到此这篇关于vue3+element-plus 实现动态菜单和动态路由的渲染的项目实践的文章就介绍到这了,更多相关vue3+element-plus 动态菜单和动态路由内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!