vue:菜单栏联动内容页面tab

一、需求

需要实现效果:左侧菜单栏与右侧内容部分联动,当点击左侧的菜单,右侧会展示对应的tab,没有点击时,不展示(如刚进入页面没有点击菜单,则没有tab);点击后没有关闭tab再打开其他菜单(如测试项目2),则测试项目2的tab高亮为选中状态。

实现效果:

二、整体实现思路

1.环境:vue、element-ui

2.首先,在el-tab-pane中,是展示的tab(如上图的测试项目1、测试项目2)。因此我们创建了一个数组activeTabs来储存tab的信息。

  • :label="getTabTitle(route.path)" 对应的则是tab展示的标题内容,我用了一个方法getTabTitle获取路由对应的标题。
  • :name="route.meta.title" 则是与el-tabs下的 v-model="activeName"相对应,如果name的值与v-model的值一样,则表示当前选中的tab。
  • 代码中,v-model="activeName" 用于控制 el-tabs 组件的当前活动标签,而 :name="route.meta.title" 用于为每个标签指定一个唯一的名称,这样就可以通过这个名称来确定当前选中的标签。通过这两个指令影响到同一个数据(例如 activeNameroute.meta.title),以达到实现标签切换的效果。
  • 当前选中的状态由 @tab-click="selectTab" 事件处理器决定。当点击一个标签时(tab-click 事件),会触发 selectTab 方法。在 selectTab 方法中,this.activeName 属性根据点击的标签的 meta.title 进行更新。v-model="activeName" 会自动反映这个变化,使得 el-tabs 组件根据 activeName 的值来确定哪个标签是当前选中的,从而产生高亮效果。
  •  @edit="handleTabsEdit"是为了对tab做一些操作,点击 tabs 的新增按钮或 tab 被关闭后触发。

值得注意的是v-model="activeName"、selectTab、 :name="route.meta.title"几个的对应关系,以及其数据结构。

   <el-tabsv-model="activeName"editable@edit="handleTabsEdit"@tab-click="selectTab"><el-tab-panev-for="(route, index) in activeTabs":key="index":label="getTabTitle(route.path)":name="route.meta.title"></el-tab-pane></el-tabs>

三、我遇到的问题

1.数据结构问题,一开始拿到的只是name或label、path,这样是不行的,最好还是拿到当前对应菜单栏的完整router,方便我们操作。

2.点击菜单栏对应的tab没有高亮但内容显示了

3.点击关闭tab,tab关闭了但下面的内容没有关闭,没有跳转到下一个剩余tab的内容。

4.点击tab之间相互切换,功能是正常的页面内容切换,但存在问题tab没有高亮,有时候要点击两次才会高亮,判段问题是出在没有更新调用selectTab。

四、具体代码

<template><section class="app-main"><el-tabsv-model="activeName"editable@edit="handleTabsEdit"@tab-click="selectTab"><el-tab-panev-for="(route, index) in activeTabs":key="index":label="getTabTitle(route.path)":name="route.meta.title"></el-tab-pane></el-tabs><transition name="fade-transform" mode="out-in">  //展示具体页面内容<content   //自定义组件><div class="router-inner-container"><router-view v-show="activeName" :key="key" /> //v-show="activeName"非常重要,注意不要用v-if,用来与当前tab对应,即关闭tab也关闭当前内容。</div></content></transition></section>
</template><script>
import { mapGetters } from 'vuex'; //引入vuex,来拿到我的所有菜单路由export default {name: 'AppMain',props: {noTag: {type: Boolean,default: false},noMap: {type: Boolean,default: false}},data() {return {activeName: null, // 默认选中第一个 tabactiveTabs: [] // 存储当前显示的 tab};},computed: {...mapGetters(['sidebar', 'sidebarRouters']), //菜单所有路由sidebarRouterskey() {return this.$route.path;},isStatisticsView() {if (this.$route.path == '/home/index') {return true;} else {return false;}}},methods: {selectTab(tab, event) {if (Array.isArray(tab) && tab.length > 0) {  //由于数据结构问题做的判段,拿到activeName this.activeName = tab[0].meta.title;} else if (typeof tab === 'object' && tab.meta) {this.activeName = tab.meta.title;} else if (Array.isArray(tab) && !tab.length > 0) {this.activeName = ''; //当所有tab都关闭时,关闭所有内容,否则页面会tab都关闭了,但还有最后一个关闭的tab的页面内容。}},handleTabsEdit(targetName, action) {// 处理标签页编辑事件if (action === 'remove') {// 删除标签页this.removeTab(targetName);}},removeTab(targetName) {const tabs = this.activeTabs;const index = tabs.findIndex((tab) => tab.meta.title === targetName);if (index !== -1) {tabs.splice(index, 1);this.selectTab(tabs, event); //很重要,更新activeName,否则删除后不会切换下一个对应tab也不会切换页面内容}},updateActiveTabs() {const currentPath = this.$route;// 判断对象是否在 activeTabs 中存在const existsInTabs = this.activeTabs.some((tab) => tab.hasOwnProperty('path') && tab.path === currentPath.path);if (!existsInTabs) {// 如果当前路由不在 activeTabs 中,将其添加进去this.activeTabs.push(currentPath);}this.selectTab(currentPath, event); //很重要,更新activeName,否则切换菜单栏时对应的tab不会高亮不会切换},findMatchingRoute(routes, targetPath) {   //为了处理数组的for (const route of routes) {if (route.path === targetPath) {return route;}if (route.children && route.children.length > 0) {const matchingChild = this.findMatchingRoute(route.children,targetPath);if (matchingChild) {return matchingChild;}}}return null;},getTabTitle(route) {// 根据路由信息获取对应的标题const matchingRoute = this.findMatchingRoute(this.sidebarRouters, route);return matchingRoute ? matchingRoute.meta.title : '';},findMatchingMenu(routes, targetTitle) {// 递归查找匹配的菜单项for (const route of routes) {if (route.meta) {if (route.meta.title === targetTitle) {return route;}if (route.children && route.children.length > 0) {const matchingChild = this.findMatchingMenu(route.children,targetTitle);if (matchingChild) {return matchingChild;}}}}return null;}},mounted() {},watch: {$route(to, from) {if (to && to.meta && !to.meta.noMap) {this.$nextTick(() => {this.$refs.jmap.resizeMap();});}// 更新 activeTabsthis.updateActiveTabs();},activeName: {immediate: true,deep: true,handler(val, oldVal) {if (val && val !== oldVal) {const matchingMenu = this.findMatchingMenu(this.sidebarRouters, val);if (matchingMenu) {this.$router.push({ path: matchingMenu.path });  //切换tab时,切换路由来对应想要页面内容}}}}}
};
</script><style lang="scss">
.app-main {/*50 = navbar  */height: calc(100vh - 50px);width: 100%;position: relative;overflow: hidden;display: flex;flex-direction: column;background: #f3f3f3;&.no-header {height: 100vh;}
}
.fixed-header + .app-main {padding-top: 60px;
}.single-layout {.app-main {padding: 0px;}
}.map-style + .router-inner-container {position: absolute;
}
</style><style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {.fixed-header {padding-right: 15px;}
}
.no-header {.float-panel {height: 100vh;}
}
</style>

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

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

相关文章

玖章算术NineData通过阿里云PolarDB产品生态集成认证

近日&#xff0c;玖章算术旗下NineData 云原生智能数据管理平台 (V1.0&#xff09;正式通过了阿里云PolarDB PostgreSQL版 (V11)产品集成认证测试&#xff0c;并获得阿里云颁发的产品生态集成认证。 测试结果表明&#xff0c;玖章算术旗下NineData数据管理平台 (V1.0&#xff…

Maxwell介绍

一、介绍 介绍&#xff1a;它读取MySQL binlog并将数据更改作为JSON写入Kafka、Kinesis和其他流媒体平台&#xff08;目前支持&#xff1a;kafka、RabbitMQ、Redis、file、Kinesis、Nats、Google Cloud Pub/Sub、Google Cloud Bigquery、SNS&#xff09; 版本&#xff1a;从v1.…

【车载开发系列】Autosar DCM诊断管理模块

【车载开发系列】Autosar DCM诊断管理模块 【车载开发系列】Autosar DCM诊断管理模块 【车载开发系列】Autosar DCM诊断管理模块一. DCM模块概念二. DCM模块与Autosar其他模块关系1&#xff09;Dcm和PduR的交互2&#xff09;Dcm和ComM模块的交互3&#xff09;Dcm和Dem的交互4&a…

RocketMQ常见面试题及答案梳理

1、RocketMQ有什么作用&#xff1f; 异步:数据的产生方不需要关心谁来使用数据&#xff0c;只需要将数据发送到broker,后续需要管消费流程&#xff0c;Rocket也有保证消息可靠性的方案消峰&#xff1a;正常业务系统当流量激增时&#xff0c;有可能会将系统压垮&#xff0c;有了…

ChatGPT正确打开方式与GPT-4.5的key最新获取方式

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言4.5key价格泄漏ChatGPT4.0使用地址ChatGPT正确打开方式最新功能语音助手存档…

【2015~2024】大牛直播SDK演化史

大牛直播SDK的由来 大牛直播SDK始于2015年&#xff0c;最初我们只是想做个低延迟的RTMP推拉流解决方案&#xff0c;用于移动单兵等毫秒级延迟的场景下&#xff0c;我们先是实现了Android平台RTMP直播推送模块&#xff0c;当我们用市面上可以找到的RTMP播放器测试时延的时候&am…

网络设备的分类和功能、机柜布局、网络设备安装

网络互连设备根据不同层实现的机理不一样&#xff0c;又具体分为五类&#xff1a; 1、网络传输介质互联设备 2、网络物理层互联设备 3、数据链路层互联设备 4、网络层互联设备 5、应用层互联设备 常用设备 网络互联设备--互联设备 1、中继器 中继器是局域网互连的最简单…

恒创科技:云存储和网盘怎么区分出来?

随着互联网的发展&#xff0c;数据存储已成为人们日常生活中不可或缺的一部分。云存储和网盘是经常被人们提及的两种存储方式&#xff0c;均通过网络进行数据存储和访问的服务。但&#xff0c;它们在技术实现、数据安全性、访问方式和数据容量等方面存在一定的差异。要区分&…

三甲医院预约挂号系统源码,具备后台管理端和用户使用端,用户使用端包括:微信公众号、支付宝小程序

随着医疗行业的不断发展&#xff0c;预约挂号管理系统已成为医院管理中不可或缺的一部分。 预约挂号管理系统是一款综合性的预约挂号管理系统&#xff0c;帮助医院实现全方位的信息化管理&#xff0c;提高医疗服务质量和效率。支撑公众号、小程序、手机网上预约。 一款服务适用…

企业用户注册阿里云账号:为何选择企业实名认证及其五大优势

在数字化时代&#xff0c;云计算已成为企业运营不可或缺的一部分。阿里云&#xff0c;作为领先的云服务提供商&#xff0c;为企业用户提供了丰富的云产品和解决方案。但在享受这些服务之前&#xff0c;企业用户需要完成阿里云账号的注册和实名认证。本文将深入探讨为何企业用户…

小程序打包发行流程

工具 HBuilder X 、微信开发者工具、微信公众平台地址&#xff08;微信公众平台&#xff09; 配置 一、manifest.json 配置 通过 HBuilder X 打开 manifest.json 文件&#xff0c;找到 微信小程序配置&#xff0c;填写 微信小程序AppID&#xff0c;此 AppID 必须是本人有权…

Jvm相关知识(面试高级必备)

类的实例化顺序 先静态、先父后子 先静态&#xff1a;父静态>子静态 优先级&#xff1a;父类>子类 静态代码块>非静态代码块>构造函数 一个类的实例化过程&#xff1a; ①&#xff0e;父类的static代码块&#xff0c;当前类的static; ②&#xff0e;顺序执行…

freeswitch on centos dockerfile模式

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 centos7 docker上编译安装fs的流程记录&#xff0c;本文使用dockerfile模式。 环境 docker engine&#xff1a;Version 24.0.6 centos docker&#xff1a;7 freeswitch&#xff1a;v1.6.20 dockerfile 创建空目录…

力扣电话号码的组合

文章目录 题目说明做题思路代码实现代码解析 题目链接 题目说明 首先我们先分析一下这个题目题目中说呢先给出一个字符串这个字符串其实就是这个九键数字我们要按照要求将数字所代表的字符进行自由组合形成一个字符串并且这个字符串的长度和输入的数字字符串长度相同&#xff0…

第11章 GUI Page500~504 步骤三十二:打开画板文件02

各个图元类新增GetTypeName_Static()&#xff0c;并将原来的GetTypeName()改为调用静态方法实现&#xff1a; 直线&#xff1a; 圆&#xff1a; 十字&#xff1a; 矩形&#xff1a; 文字&#xff1a; tool_4_save_load.hpp添加两行 tool_4_save_load.cpp增加&#xff1a; 增加…

【资治通鉴】古代纪年法 ( 天干地支纪年法 | 木星纪年法 | 太岁纪年法 | 星次 | 天球 | 黄道带 | 四象二十八星宿 )

文章目录 一、天干地支纪年法二、木星纪年法1、星次2、天球3、黄道带 三、太岁纪年法四、四象二十八星宿1、四象与二十八星宿关联2、二十八星宿与星次关联3、西游记中的二十八星宿 2024 年 使用 天干地支纪年法是 甲辰年 , 使用 太岁纪年法是 阏逢执徐 ; 一、天干地支纪年法 天…

建筑能源管理系统

建筑能源管理系统是一种集成了先进的监测、控制、分析和优化技术的智能化系统&#xff0c;旨在提高建筑能源效率&#xff0c;降低能源消耗&#xff0c;减少环境污染&#xff0c;并为用户提供舒适、安全的建筑环境。通过监测建筑内的各种能源消耗情况&#xff0c;如电力、热水、…

arthas(阿尔萨斯)日常java代码调优使用命令

官方项目文档&#xff1a;https://gitee.com/arthas/arthas &#xff08;最权威的教学还是得官网&#xff0c;这里仅作简单记录&#xff09; 1&#xff1a;启动 java -jar arthas-boot.jar 2&#xff1a;查看cpu占用排名前三 thread -3 3&#xff1a;查看指定id thread 203 4:查…

数据结构day1

1.思维导图 2.定义一个简单宏或宏函数&#xff0c;实现两个数交换。 3.定义字符类型指针&#xff0c;指针指向n个连续堆区内存&#xff0c;输入&#xff0c;计算字符串长度 定义函数&#xff0c;实现内存申请 定义函数&#xff0c;解释字符串长度 定义函数&#xff0c;释放内…

河南文旅火爆出圈,来了解小魔推短视频矩阵的魅力!

最近几天四川文旅的抖音账号&#xff0c;1天发视频六十多条&#xff0c;增长粉丝20w&#xff0c;另外河北文旅抖音账号&#xff0c;一天发视频七十多条&#xff0c;增长粉丝30w&#xff0c;更有河南文旅抖音账号&#xff0c;单日发布上百条视频&#xff0c;实现涨粉15w&#xf…