elementui+vue实现菜单导航跟main区域的tabs联动效果
文章目录
1.前言
vue小白,做的项目用的是elementui+vue实现,在项目进行到中期时,发现对于系统还是有一些不足的,vue用的是vuex进行路由跳转,但是每次跳转都会刷新页面,重新加载,就算控制路由上写了children,也算是重新加载的,所以问题就是怎么实现菜单导航跟页面的main区域的关联,用tabs联动起来,实现可以在main区域上看到我们之前点开过的页面,提示可以回到那个页面,同时保留当前页面。
2.实现效果:
3.解决过程
在网上看了很多大佬写的文章,可能我太菜了,看了之后完全看不懂,代码放到项目里不是这个问题就是那个问题。。。。。
附大佬文章:
如果觉得我写的不适合,可以参考大佬写的文章:
vue+element-ui点击导航栏动态添加对应的tabs,并可删除
我是根据这篇文章,结合我自己的项目进行修改的,可能没有那么完善,但是只是满足我自己项目的需求,同时我也看得懂。
4.具体代码
- home页面:因为全部的代码实在是太多,不仅仅是导航栏跟tabs的两栋,还有我项目的一些具体功能代码,所以我没有全部放上来,只放了这个效果的全部代码。
html部分:
<el-main>
<el-tabs type="card" @tab-remove="removeTab" @tab-click="tabClick">
<el-tab-pane v-for="item in tabsItem"
:key="item.name"
:label="item.title"
:name="item.name"
:closable="item.closable"
:ref="item.ref">
</el-tab-pane>
</el-tabs>
<!-- 路由的占位符 -->
<transition name="fade" mode="out-in">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
</transition>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</el-main>
js部分:
<script>
import Home from '../components/Home.vue'
export default {
data() {
return {
// 被激活的连接地址
activePath: '',
// activeTab: '1', //默认显示的tab
tabIndex: 1, //tab目前显示数
tabsItem: [
{
title: '首页',
name: '1',
closable: false,
ref: 'tabs',
content: Home
}
],
tabsPath: [
{
name: "1",
path: '/home'
}
]
}
},
computed: {
activeNav() { //当前激活的导航
return this.$route.path
}
},
methods: {
removeTab(targetName) { //删除Tab
let tabs = this.tabsItem; //当前显示的tab数组
let activeName = this.activeTab; //点前活跃的tab
//如果当前tab正活跃 被删除时执行
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
let nextTab = tabs[index + 1] || tabs[index - 1];
if (nextTab) {
activeName = nextTab.name;
this.tabClick(nextTab)
}
}
});
}
this.activeTab = activeName;
this.tabsItem = tabs.filter(tab => tab.name !== targetName);
//在tabsPath中删除当前被删除tab的path
this.tabsPath = this.tabsPath.filter(item => item.name !== targetName)
},
tabClick(thisTab) {
/*
* thisTab:当前选中的tabs的实例
* 通过当前选中tabs的实例获得当前实例的path 重新定位路由
* */
let val = this.tabsPath.filter(item => thisTab.name == item.name)
this.$router.push({
path: val[0].path
})
}
},
watch: {
'$route': function (to) { //监听路由的变化,动态生成tabs
let flag = true //判断是否需要新增页面
const path = to.path
if (Object.keys(to.meta).length != 0) {
for (let i = 0; i < this.$refs.tabs.length; i++) {
if (i != 0) { //首页不判断 如果页面已存在,则直接定位当页面,否则新增tab页面
if (this.$refs.tabs[i].label == to.meta.name) {
this.activeTab = this.$refs.tabs[i].name //定位到已打开页面
flag = false
break
}
}
}
//新增页面
if (flag) {
//获得路由元数据的name和组件名
const thisName = to.meta.name
const thisComp = to.meta.comp
//对tabs的当前激活下标和tabs数量进行自加
let newActiveIndex = ++this.tabIndex + ''
//动态双向追加tabs
this.tabsItem.push({
title: thisName,
name: String(newActiveIndex),
closable: true,
ref: 'tabs',
content: thisComp
})
this.activeTab = newActiveIndex
/*
* 当添加tabs的时候,把当前tabs的name作为key,path作为value存入tabsPath数组中
* key:tabs的name
* value:tabs的path
* {
* key: name,
* value: path
* }
* ///后面需要得到当前tabs的时候可以通过当前tabs的name获得path
* */
if (this.tabsPath.indexOf(path) == -1) {
this.tabsPath.push({
name: newActiveIndex,
path: path
})
}
}
}
}
}
}
</script>
同时需要对原来的项目路由配置进行一些修改
改完之后就差不多了,代码写就到这里。
如果有写错或者不足的地方,还请在评论区指正!!我会及时修改!!!!!!
请尊重原创,如需转载,还请注明原作者,原文链接,谢谢啦!!!