elementui+vue实现菜单导航跟main区域的tabs联动效果

7 篇文章 1 订阅

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>

同时需要对原来的项目路由配置进行一些修改

在这里插入图片描述
改完之后就差不多了,代码写就到这里。

如果有写错或者不足的地方,还请在评论区指正!!我会及时修改!!!!!!
请尊重原创,如需转载,还请注明原作者,原文链接,谢谢啦!!!
  • 13
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值