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

news2024/11/15 11:00:04

在 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 的动态菜单实现,它可以自动根据路由配置渲染出相应的菜单结构,并且能够响应路由变化,高亮显示当前激活的菜单项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1947671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL labs-SQL注入(五,使用sqlmap进行cookie注入)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 引言&#xff1a; Cookie 是一些数据, 存储于你电脑上的文本文件中。当 web 服务器向浏览器发送 web 页面时&#xff0c;在连接关闭后&#xff0c;服务端不会记录用户的信息。Cookie…

新形势下职业教育大数据人才培养策略

一、引言 随着信息技术的飞速发展&#xff0c;大数据已成为驱动经济社会变革的关键力量。在新形势下&#xff0c;职业教育作为技术技能人才培养的重要阵地&#xff0c;面临着如何适应大数据时代要求、提升人才培养质量的紧迫任务。当前&#xff0c;职业教育在大数据人才培养方…

【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !

目录 C语言中指针的大小1. 指针大小的基本概念1.1 32位系统1.2 64位系统 2. 指针大小示例2.1 32位系统输出2.2 64位系统输出 3. 指针大小与数据类型无关示例输出示例 4. 跨平台的指针大小示例输出示例 5. 关键点总结5.1 指针大小与平台关系5.2 跨平台编程注意事项 6. 指针大小示…

PySide(PyQt)的小部件通过伪状态以及自定义特性改变外观

1、通过伪状态来改变外观 伪状态是一种特殊的状态&#xff0c;通常用于描述控件在特定条件下的外观变化。这些状态不是控件的实际属性&#xff0c;而是用于在样式表中应用不同样式的标记。 以QPushButton为例。在 PySide6 中&#xff0c;QPushButton 具有多种伪状态&#xff0c…

卷积神经网络(二)-AlexNet

前言&#xff1a; AlexNet是2012年ImageNet竞赛冠军&#xff08;以领先第二名10%的准确率夺得冠军&#xff09;获得者Hinton和他的学生Alex Krizhevsky设计的,在ILSVRC-2010测试集上取得了top-1错误率37.5%,top-5错误率17.0%&#xff08;优于第二名的16.4%&#xff09;,明显优…

科技快讯丨智驱未来,校企共融:浪潮海岳携手山东大学软件学院开展低代码开发实训活动

近日&#xff0c;山东大学软件学院暑期实训活动圆满落幕。作为领先的企业数字化转型优秀服务商&#xff0c;浪潮海岳主导的低代码开发课题吸引了众多师生参训&#xff0c;取得了良好成效。 当前&#xff0c;低代码开发已成为软件行业降本增效、提升用户体验的必然选择&#xff…

labview实现两台电脑共享变量传输及同步

因为工作需要&#xff0c;需要实现多台主机间进行数据传输&#xff0c; 有两个备选方案&#xff0c; 1&#xff1a;建立tcp&#xff0c;然后自己解包 2&#xff1a;就是通过共享变量传输 虽然共享变量也是建立在TCP/IP上面的&#xff0c;但是不用自己解包呀 关于共享变量网络上…

vivo手机恢复出厂设置在哪里?清除数据后如何找回?2个技巧

随着使用时间的增长&#xff0c;手机可能会因为累积的缓存文件、不必要的数据或软件问题而出现性能下降或系统运行缓慢。为了解决这些问题&#xff0c;执行恢复出厂设置成为了一种流行的解决方案。那么&#xff0c;vivo手机恢复出厂设置在哪里&#xff1f;数据清除后该如何找回…

CCRC-DSO数据安全官:打造数据“冷链”,做强做大数据产业

在7月22日国新办举办的“推动高质量发展”系列新闻发布会上&#xff0c;国家数据局局长刘烈宏宣布&#xff0c;为响应党的二十届三中全会的决策&#xff0c;将加速推进数字经济发展机制的构建和完善数据要素市场制度。 他强调了对地方试点探索的支持&#xff0c;目标是建立强大…

基础复习(数组)

数组 一维数组 1.静态初始化 数据类型[] 数组名 new 数据类型[]{元素1,元素2,元素3,...}; 数据类型[] 数组名 {元素1,元素2,元素3...}; 2.动态初始化 数组存储的元素的数据类型[] 数组名字 new 数组存储的元素的数据类型[长度]; 3.执行原理 变量存储的是数组的地址值。…

Pyqt5新手教程

PyQt界面开发的两种方式&#xff1a;可视化UI 编程式UI &#xff08;1&#xff09;可视化UI&#xff1a;基于Qt Designer可视化编辑工具进行组件拖放、属性设置、布局管理等操作创建界面。 一是将其保存为.ui文件&#xff0c;然后在PyQt应用程序中加载和使用.ui文件。 二是使用…

接口自动化测试框架实战-3-文件读写封装

上一小节我们详细介绍了项目中所使用的接口文档&#xff0c;本小节我们将进入到接口测试框架第一个部分通用函数commons的开发&#xff0c;本小节我们重点完成文件读写方法的封装。 首先为什么要封装文件读写的方法&#xff0c;原因有如下几点&#xff1a; 读接口配置&#x…

B站音视频分开 大小问题

音频是33331 kb&#xff0c;视频是374661 kb 合并之后却是2561363 kb 这可能是B站音频和视频分开的原因吧

html实现酷炫美观的可视化大屏(十种风格示例,附源码)

文章目录 完整效果演示1.蓝色流线风的可视化大屏1.1 大屏效果1.2 大屏代码1.3 大屏下载 2.地图模块风的可视化大屏2.1 大屏效果2.2 大屏代码2.3 大屏下载 3.科技轮动风的可视化大屏3.1 大屏效果3.2 大屏代码3.3 大屏下载 4.蓝色海洋风的可视化大屏4.1 大屏效果4.2 大屏代码4.3 …

深入指南:VitePress 如何自定义样式

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

边缘计算网关项目(含上报进程、32Modbus采集进程、设备搜索响应进程源码)

目录 边缘层 架构说明 包含知识点 数据上报进程 功能描述 功能开发 上报线程 数据存储线程 指令处理线程 项目源码 上报模块.c代码&#xff1a; 上报模块Makefile代码&#xff1a; STM32采集模块.c代码 设备搜索响应模块Linux部分.c代码 设备搜索响应模块Qt端代码.h …

计算机毕业设计-程序论文-高校智能排课系统

本系统开发采用技术为JSP、Bootstrap、Ajax、SSM、Java、Tomcat、Maven 此文章为本人亲自指导加编写&#xff0c;禁止任何人抄袭以及各类盈利性传播&#xff0c; 相关的代码部署论文ppt代码讲解答辩指导文件都有可私要 项目源码&#xff0c;请关注❥点赞收藏并私信博主&#xf…

UML通信图建模技术及应用例

新书速览|《UML 2.5基础、建模与设计实践》 在对系统的动态行为进行建模时&#xff0c;通信图常被用于按组织结构对控制流进行建模。与顺序图一样&#xff0c;一个单独的通信图只能显示一个控制流。 使用通信图建模时可以遵循如下策略&#xff1a; &#xff08;1&#xff09…

操作系统杂项(九)

目录 一、简述sleep和wait的区别 1、sleep 2、wait 3、区别 二、简述线程池的设计思路&#xff0c;线程池中线程数量的决定因素 1、设计思路 2、线程池中线程数量 三、进程和线程相比&#xff0c;为何更慢 四、简述Linux零拷贝的原理 1、概念 2、优点 3、原理 五、…

MySQL第一阶段:多表查询、事务

继续我的MySQL之旅&#xff0c;继续上篇的DDL、DML、DQL、以及一些约束&#xff0c;该到了多表查询和事务的学习总结&#xff0c;以及相关的案例实现&#xff0c;为未来的复习以及深入的理解做好知识储备。 目录 多表查询 连接查询 内连接 外连接 子查询 事务 事务简介…