首页 前端知识 vue3 element-plus 实现动态菜单和动态路由的渲染

vue3 element-plus 实现动态菜单和动态路由的渲染

2025-02-24 13:02:15 前端知识 前端哥 382 262 我要收藏

在 Vue.js 中,使用 Vue Router 管理路由数据,并将其用于渲染 el-menu(Element UI 的菜单组件)通常涉及以下几个步骤:

  1. 定义路由元数据
    在你的路由配置中,为每个路由项添加 meta 字段,这个字段可以包含任何你想要传递给菜单的数据,例如菜单名称、图标等。

  2. 获取路由数据
    使用 router 实例的 getRoutes() 方法来获取当前注册的所有路由信息。

  3. 过滤和格式化数据
    根据需要过滤和格式化路由数据,以便它们可以被 el-menu 组件使用。

  4. 将数据传递给组件
    将格式化好的路由数据传递给使用 el-menu 的组件。

  5. 使用 v-for 渲染菜单
    在组件的模板中,使用 v-for 指令来遍历路由数据,并渲染 el-menu

实现效果

在这里插入图片描述

路由配置

首先是路由配置,要实现这个路由配置,你需要完成以下几个步骤:

  1. 注册 Vue Router:确保你已经在你的 Vue 应用中安装并注册了 Vue Router。

  2. 定义路由:使用 Vue Router 的 addRoute 方法动态添加路由。

  3. 使用路由:在应用中使用 <router-view> 来渲染对应的组件。

  4. 渲染菜单:如果你需要根据路由配置动态渲染菜单(例如使用 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-coloractive-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 方法找到根路由 '/' 的子路由,并筛选出包含 metameta.title 的路由,存储到 list.value

计算属性

  • hasChilden:计算属性,筛选出 list.value 中具有子菜单的路由。
  • noChilden:计算属性,筛选出 list.value 中没有子菜单的路由。

导航处理函数

  • handlemenu:处理无子菜单项的点击事件,使用 router.push 方法导航到点击的菜单项路径。
  • handlemenuchild:处理有子菜单项的点击事件,拼接父菜单和子菜单的路径,然后导航。

激活状态

  • activeMenu:计算属性,根据当前路由的路径 route.path 设置激活的菜单项。

样式部分 (<style>)

  • 定义了一些基本的样式来美化菜单,例如移除边框、设置字体大小和加粗。

总结

这个组件通过 Vue Router 的 useRouter 钩子获取当前路由的配置信息,并根据这些信息动态生成菜单项。使用 computed 属性来区分哪些路由有子菜单,哪些没有,然后相应地渲染 el-menu-itemel-sub-menu。点击菜单项时,使用 router.push 方法来改变页面的路由,实现导航功能。并通过 useRoute 钩子获取当前激活的路由,然后设置 activeMenu 来决定哪个菜单项应该处于激活状态。这个组件是一个结合 Vue Router 和 Element UI 的动态菜单实现,它可以自动根据路由配置渲染出相应的菜单结构,并且能够响应路由变化,高亮显示当前激活的菜单项。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/21138.html
标签
评论
还可以输入200
共0条数据,当前/页
发布的文章

C/C | 每日一练 (2)

2025-02-24 13:02:49

Linux性能监控工具汇总

2025-02-24 13:02:48

Python常见面试题的详解16

2025-02-24 13:02:48

QQ登录测试用例报告

2025-02-24 13:02:47

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!