vue实现el-menu与el-tabs联动

效果图如下:

在这里插入图片描述

当标签栏很多的时候效果图如下:

在这里插入图片描述

左侧菜单布局 ($route.path高亮显示激活路由 :default-active="$route.path"
<el-menu:default-active="$route.path"class="el-menu-vertical-demo"background-color="#323744"text-color="#fff"active-text-color="#409eff":collapse="iscollapse"unique-opened:collapse-transition="false"router><template v-for="(item, index) in menuList"><!-- 有下拉 --><el-submenu v-if="item.children" :index="item.id" :key="index"><template slot="title"><svg-icon :className="item.icon" :iconClass="item.icon"></svg-icon><span>{{ item.title }}</span></template><el-menu-item-groupv-for="(item, index) in item.children":key="index"><el-menu-item :index="item.path" @click="clickMenu(item)"><template slot="title"><svg-icon :className="item.icon" :iconClass="item.icon"></svg-icon><span>{{ item.subtitle1 }}</span></template></el-menu-item></el-menu-item-group></el-submenu><!-- 没有下拉 --><el-menu-item v-else :key="index" :index="item.path" @click="clickMenu(item)"><svg-icon :className="item.icon" :iconClass="item.icon"></svg-icon><span slot="title">{{ item.subtitle1 }}</span></el-menu-item></template></el-menu>
模拟数据如下:(以下路径均需在router/index.js里面进行配置)
menuList: [{id: "9",subtitle1: "首页",icon: "shangjiadianpu",path: "/welcome",},{id: "1",title: "用户管理",icon: "huangguanyonghu",children: [{id: "1-1",subtitle1: "时间-moment",icon: "huangguanyonghu",path: "/user",},{id: "1-2",subtitle1: "删除用户",icon: "huangguanyonghu",img: require("@/assets/logo.png"),path: "/user2",},{id: "1-3",subtitle1: "图片放大",icon: "huangguanyonghu",path: "/user3",},],},{id: "2",title: "表格",icon: "ershoujiaoyi",children: [{id: "2-1",subtitle1: "表格排序",icon: "ershoujiaoyi",path: "/tableSort",},{id: "2-2",subtitle1: "动画",icon: "ershoujiaoyi",path: "/animation",},{id: "2-3",subtitle1: "权限3",icon: "ershoujiaoyi",path: "/limit3",},],},{id: "6",subtitle1: "拖拽-sortablejs",icon: "shangpuchuzu",path: "/sortable",},{id: "7",title: "功能",icon: "ershoujiaoyi",children: [{id: "7-1",subtitle1: "上下滚动",icon: "ershoujiaoyi",path: "/numscroll",},{id: "7-9",subtitle1: "数字滚动",icon: "ershoujiaoyi",path: "/icountup",},{id: "7-2",subtitle1: "动画",icon: "ershoujiaoyi",path: "/animation",},{id: "7-3",subtitle1: "调用摄像头",icon: "ershoujiaoyi",path: "/opencamera",},{id: "7-4",subtitle1: "裁剪图片",icon: "ershoujiaoyi",path: "/cropperjs",},{id: "7-5",subtitle1: "裁剪图片2",icon: "ershoujiaoyi",path: "/vuecropper",},{id: "7-6",subtitle1: "打印功能",icon: "ershoujiaoyi",path: "/printjs",},{id: "7-7",subtitle1: "vue-pfd预览",icon: "ershoujiaoyi",path: "/vuepdf",},{id: "7-8",subtitle1: "内嵌iframe",icon: "ershoujiaoyi",path: "/iframepdf",},{id: "7-10",subtitle1: "放大镜功能",icon: "ershoujiaoyi",path: "/magnifier",},{id: "7-11",subtitle1: "多表头表格",icon: "ershoujiaoyi",path: "/xlsx",},{id: "7-12",subtitle1: "单表头表格",icon: "ershoujiaoyi",path: "/xlsx2",},{id: "7-13",subtitle1: "Vuecontextmenu",icon: "ershoujiaoyi",path: "/vuecontextmenu",},{id: "7-14",subtitle1: "vcontextmenu",icon: "ershoujiaoyi",path: "/vcontextmenu",},{id: "7-15",subtitle1: "表格合并",icon: "ershoujiaoyi",path: "/tablehebing",},{id: "7-16",subtitle1: "日期选择",icon: "ershoujiaoyi",path: "/datepicker",},{id: "7-17",subtitle1: "treeselect",icon: "ershoujiaoyi",path: "/treeselect",},{id: "7-19",subtitle1: "大屏数据",icon: "ershoujiaoyi",path: "/datav",},{id: "7-20",subtitle1: "左右菜单联动",icon: "ershoujiaoyi",path:'/leftrightmenu'},{id: "7-18",subtitle1: "测试页面",icon: "ershoujiaoyi",path: "/test",},],},],

主要内容区域标签栏布局如下:

	<el-tabsclass="vab-tabs-content"v-model="activeIndex"type="card"@tab-click="clickTab"@tab-remove="removeTab"><el-tab-panev-for="item of openTab"v-if="openTab.length":key="item.name":label="item.name":name="item.route":closable="isNoClosable(item)"></el-tab-pane></el-tabs>
标签栏样式
/deep/.el-tabs__header .el-tabs__nav{border:none;}/deep/.el-tabs--card>.el-tabs__header{border:none;}/deep/.el-tabs__header .el-tabs__item{padding:0 30px;border:none}/deep/.el-tabs__header .el-tabs__item.is-active {color: #1890ff;background: #e8f4ff;outline: none;-webkit-mask: url(~@/assets/images/tabs-bg.png);mask: url(~@/assets/images/tabs-bg.png);-webkit-mask-size: 100% 100%;mask-size: 100% 100%;
}/deep/.el-tabs__header .el-tabs__item:hover {color: #515a6e;background: #dee1e6;-webkit-mask: url(~@/assets/images/tabs-bg.png);mask: url(~@/assets/images/tabs-bg.png);-webkit-mask-size: 100% 100%;mask-size: 100% 100%;}/deep/.el-tabs--card > .el-tabs__header .el-tabs__item.is-closable:hover {padding-left: 30px;padding-right: 30px;}/deep/.el-tabs__header .el-tabs__item.is-active.is-closable {padding-left: 30px;padding-right: 30px;
}/deep/.el-tabs__header .el-tabs__item.is-active:hover {color: #1890ff !important;background: #e8f4ff !important;// padding: 0 30px 0 30px;}.el-tabs__header .el-tabs__item.is-active:hover {color: #1890ff;background: #e8f4ff;-webkit-mask: url(~@/assets/images/tabs-bg.png);mask: url(~@/assets/images/tabs-bg.png);-webkit-mask-size: 100% 100%;mask-size: 100% 100%;}
创建一个仓库模块 @/store/Modules/tabs.js

在这里插入图片描述

tabs.js代码如下

export default{namespaced: true,  //开启命名空间state: {openTab: JSON.parse(sessionStorage.getItem('openTab'))|| [],activeIndex: ''},mutations: {add_tabs (state, data) {//如果等于-1说明tabs不存在那么插入,否则什么都不做//findindex找角标,循环判断一下,如果等于那么就代表有相同的,就不必添加,如果找不到那就是-1.就添加let result = state.openTab.findIndex(item => item.name === data.name);result === -1 ? state.openTab.push(data) : '';// 存到本地 页面刷新不丢失sessionStorage.setItem('openTab',JSON.stringify(state.openTab))},delete_tabs (state, route) {let index = 0for (let gohh of state.openTab) {if (gohh.route === route) {break}index++}state.openTab.splice(index, 1)// 存到本地 页面刷新不丢失sessionStorage.setItem('openTab',JSON.stringify(state.openTab))},set_active_index (state, index) {console.log(index);state.activeIndex = index}}
}
将tab.js模块引入@store/index.js

import Vue from 'vue'
import Vuex from 'vuex
import tabs from './Modules/tabs'
Vue.use(Vuex)
export default new Vuex.Store({state: { },mutations: {},actions: {},modules: {tabs}
})
主要逻辑代码如下:
在主要内容区域引入如下代码获取tabs.js仓库里面的值在页面进行渲染
  computed: {openTab () {return this.$store.state.tabs.openTab},activeIndex: {get () {return this.$store.state.tabs.activeIndex},set (val) {this.$store.commit('tabs/set_active_index', val)}}},
左侧菜单导航绑定点击事件clickMenu,去触发仓库的add_tabs事件,把数组添加到openTab数组里面(添加前需要判断openTab是否有当前值,有就不添加,反之添加),把activeIndex也改变
clickMenu(val){//备注 :分模块触发事件可参考vue官网  '模块名/事件名'this.$store.commit('tabs/add_tabs',{route: val.path , name: val.subtitle1 })this.$store.commit('tabs/set_active_index', val.path)},
标签绑定点击事件clickTab 跳转到对应路由,给标签叉叉绑定removeTab (tab-remove 点击 tab 移除按钮后触发 被删除的标签的 name)拿到对应的路由进行判断

1、如果是首页则不删除;
2、如果删除的高亮激活这一项,则跳转到最后openTab数组的最后一项并高亮;
3、如果删除的不是高亮激活这一项,则不跳转,高亮激活项不变。

clickTab (tab) {console.log(tab);this.$router.push({path: this.activeIndex})},removeTab (target) {if(target == '/'||target == '/welcome'){return}this.$store.commit('tabs/delete_tabs', target)if (this.activeIndex === target) {// 设置当前激活的路由if (this.openTab && this.openTab.length >= 1) {console.log('=============', this.openTab[this.openTab.length - 1].route)this.$store.commit('tabs/set_active_index', this.openTab[this.openTab.length - 1].route)this.$router.push({path: this.activeIndex})}}},
el-tab-pane标签绑定属性 :closable="isNoClosable(item)判断el-tab-pane是否显示叉叉,除了首页不显示,其他均显示
isNoClosable(item){return item.route !== '/welcome'},
刷新时以当前路由做为tab加入tabs,当前路由不是首页时,添加首页以及另一页到store里,并设置激活状态,当前路由是首页时,添加首页到store,并设置激活状态(注意:this.$route.meta.title的title值要和菜单数据里面的subtitle1名称保持一致!!!)

在这里插入图片描述

mounted () {console.log(this.$route);// 刷新时以当前路由做为tab加入tabs// 当前路由不是首页时,添加首页以及另一页面到store里,并设置激活状态// 当前路由是首页时,添加首页到store,并设置激活状态if (this.$route.path !== '/welcome') {this.$store.commit('tabs/add_tabs', {route: '/welcome' , name: '首页'})this.$store.commit('tabs/add_tabs', {route: this.$route.path , name: this.$route.meta.title })this.$store.commit('tabs/set_active_index', this.$route.path)} else {this.$store.commit('tabs/add_tabs', {route: '/welcome', name: '首页'})this.$store.commit('tabs/set_active_index', '/welcome')}}

实现思路大致就是这样,主要自己项目的数据稍作修改。

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

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

相关文章

PaaS、 IaaS 和 SaaS 的区别

我感觉我有点捂了 iaas&#xff0c;paas&#xff0c;和saas的区别&#xff0c;以及他们啥意思了 简单说就是&#xff0c;一个公司有很多项目&#xff0c;要管理这些项目&#xff0c;每个项目都有很多组成部分需要管理的地方&#xff0c;例如&#xff0c;存储代码&#xff0c;例…

掌握5个关键点,搞定语音识别测试!

现在市面上的智能电子产品千千万&#xff0c;为了达到人们使用更加方便的目的&#xff0c;很多智能产品都开发了语音识别功能&#xff0c;用来语音唤醒进行交互&#xff1b; 另外&#xff0c;各大公司也开发出来了各种智能语音机器人&#xff0c;比如小米公司的“小爱”&#…

UE5 操作WebSocket

插件&#xff1a;https://www.unrealengine.com/marketplace/zh-CN/product/websocket-client 参考&#xff1a;http://dascad.net/html/websocket/bp_index.html 1. 安装Plugings 2.测试websocket服务器 http://www.websocket-test.com/ 3.连接服务器 如果在Level BP里使用&a…

4-11 四个数排序

#include<stdio.h> int main(){int t,a,b,c,d;printf("请输入四个数&#xff1a;");scanf("%d %d %d %d",&a,&b,&c,&d);printf("a%d,b%d,c%d,d%d\n",a,b,c,d);if(a>b){ta;ab;bt;}if(a>c){ta;ac;ct;}if(a>d){ta;a…

通过AppLink把拼多多热门榜单商品同步至小红书

上篇说到AppLink当中定时调度方式如何配置&#xff0c;这次来演示一下&#xff0c;如何把热门榜单信息同步至小红书 1.拉取一个定时器作为触发动作&#xff0c;通过配置定时器调度时间将定时策略配置为每天执行一次 2.触发动作完成后通过好单库获取拼多多每日热门榜单&#xf…

UE5、CesiumForUnreal实现加载GeoJson绘制盒体(Box)功能(StaticMesh方式)

文章目录 1.实现目标2.实现过程2.1 实现原理2.2 具体代码2.3 应用测试2.3.1 材质2.3.2 蓝图测试3.参考资料1.实现目标 与之前基于StaticMesh创建Polygon和Wall类似,本文通过读取本地GeoJson数据,在UE中以staticMeshComponent的形式绘制出盒体Box,支持Editor和Runtime模式,在…

UE4基础篇十五:AI行为树

一、学习完教程后需要掌握知识点 1.1、基础概念: 1.1 行为树:控制并显示AI的决策制定过程 1.2 黑板:可以看做是行为树的创建一些公有变量,外部可以修改行为树黑板的变量值,达到修改行为树状态的逻辑 1.3 环境查询: 获取地图环境中的信息进行一个筛选,查找到所需要的的…

性能小课堂:Jmeter录制手机app脚本!

环境准备&#xff1a;1.手机2.wifi3.Jmeter 具体步骤&#xff1a; 1、启动Jmeter&#xff1b; 2、“测试计划”中添加“线程组”&#xff1b; 3、“工作台”中添加“HTTP代理服务器”&#xff1b; 4、配置代理服务器&#xff1a;Global Settings下面的端口配置&#xff1a…

集成仿真软件 PLEXOS 9.0 授权永久完美

PLEXOS是由能源示例发布的能源市场集成仿真软件。能源市场是一个充满活力和活力的市场&#xff0c;在这个大市场中有各种各样的数据和信息模型。观看每日市场发展和大量数据可能会使您感到困惑&#xff0c;并难以进行未来的投资和分析。使用集成和全面的方法是应对这一挑战的唯…

随笔-事儿就这么个事儿

好久没写了&#xff0c;小A要催更&#xff0c;还答应让我写一下他的经历&#xff0c;这还有啥说的&#xff0c;开整。 1、升级 前段时间登录公司的办公系统处理一个事务申请&#xff0c;发现有个粗体标红的通知&#xff0c;是关于今年的晋升名单公示。进去看了一眼&#xff0…

养猫7年:猫罐头牌子哪个好用?5款口碑好的猫罐头推荐!

猫罐头牌子哪个好用&#xff1f;刚开始养猫真的好心累&#xff0c;因为一开始啥也不懂&#xff0c;关于猫猫的饮食这也不会选那也不会选&#xff0c;就很容易踩雷&#xff0c;为此花了不少钱&#xff0c;相信很多新手铲屎官现在也处于这种状态吧。 作为一个养猫7年的资深铲屎官…

流程变量的设置和获取

流程变量在整个工作流中扮演很重要的作用。例如&#xff1a;请假流程中有请假天数、请假原因等一些参数都为流程变量的范围。流程变量的作用域范围是只对应一个流程实例。也就是说各个流程实例的流程变量是不相互影响的。这篇博文就简单的为大家介绍下流程变量的设置和获取。 …

细节决定成败——我的日志去哪了?

概述 编写本文档的目的有两点。 本周遇到了一个日志丢失的问题&#xff0c;经过分析&#xff0c;觉得挺有意思的。向大家分享一下我的分析及解决思路。应该在很多项目中都会有该问题。领导和我私下讨论过多次&#xff0c;当前的autodomain代码对文件读取的频率太高了,如何去避…

Spring框架学习 -- 核心思想

目录 (1) Spring是什么? (2) 什么是IOC容器? (3) 从传统开发认识spring (4) 这种传统开发的缺陷 (5)解决传统开发中的缺陷 (6) 对比总结规律 (7) 理解IOC 创作不易多多支持 (1) Spring是什么? 我们常说的Spring的全称是: Spring Framework(Spring框架), 它是一个开源…

北醒携全球首款256线车规量产激光雷达亮相广州国际车展

11月17日&#xff0c;北醒携全球首款256线车规量产激光雷达亮相广州国际车展。在车展期间&#xff0c;北醒还公布了与广州花都区人民政府达成投资合作&#xff0c;获滴滴自动驾驶投资以及与捷普联合打造的全球首条量产256线级别车规激光雷达的生产线即将贯通的等多条利好信息&a…

2023-11-20 LeetCode每日一题(最大子数组和)

2023-11-20每日一题 一、题目编号 53. 最大子数组和二、题目链接 点击跳转到题目位置 三、题目描述 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的…

C语言童年生活二三事(ZZULIOJ1091:童年生活二三事(多实例测试))

题目描述 Redraiment小时候走路喜欢蹦蹦跳跳&#xff0c;他最喜欢在楼梯上跳来跳去。 但年幼的他一次只能走上一阶或者一下子蹦上两阶。 现在一共有N阶台阶&#xff0c;请你计算一下Redraiment从第0阶到第N阶共有几种走法。 输入&#xff1a;输入包括多组数据。 每组数据包括一…

Python开源自动化工具Playwright安装及介绍

一个非常强大的自动化项目叫 playwright-python 它支持主流的浏览器&#xff0c;包含&#xff1a;Chrome、Firefox、Safari、Microsoft Edge 等&#xff0c;同时支持以无头模式、有头模式运行&#xff0c;并提供了同步、异步的 API&#xff0c;可以结合 Pytest 测试框架 使用&…

Kafka(四)消费者消费消息

文章目录 如何确保不重复消费消息&#xff1f;消费者业务逻辑重试消费者提交自定义反序列化类消费者参数配置及其说明重要的参数session.time.ms和heartbeat.interval.ms和group.instance.id增加消费者的吞吐量消费者消费的超时时间和poll()方法的关系 消费者消费逻辑启动消费者…

万宾科技智能井盖传感器,提升市政井盖健康

市政井盖就是城市里不可或缺的基础设施之一&#xff0c;关于它的监测工作可马虎不得。它承载着保护市民的交通安全以及城市正常运转的重要使命。虽然现在城市化的速度很快&#xff0c;但是传统的市政井盖管理方式变得有些力不从心了。井盖的覆盖范围很广&#xff0c;如果单单依…