Vue路由+Tab组件实现多页签功能

在vue单页面应用中,当点击导航菜单时会切换路由,一般是在中间的router-view路由视图中直接显示对应路由的页面组件,那么本编就介绍一下如何使用vue路由配合tab组件实现多页签功能,打开一个新的菜单路由时变成弹出一个新的tab页签,并且随时可以切换到之前的页面,保留之前的组件状态。

image.png

当前打开的tab需要在data中以一个数组的方式维护(openTab),默认显示首页
main.vue:

     openTab: [
        {
          title: "首页",
          name: "/Index", //路由
          closable: false, //首页不可关闭
          componentName: "index" //组件名称用于keepalive缓存
        }
      ],

componentName是对应tab中页面组件的name值,所以每一个组件都必须设置自己的name值。

Vue路由+Tab组件实现多页签功能_第1张图片
下面看template如何实现,首先加入elementUItab组件:

      

注意router-view并没有放在el-tab-pane中,而是抽到了外面,tab共用这一块试图,因为如果使用了多试图的方式会出现元素id属性可能相同的问题。同时使用keep-alive缓存组件的状态。
可以使用include存储当前tab的组件名name列表实现tab视图的缓存,这样互相切换就不需要重新加载组件,但是要特别注意组件的name的唯一。

removeTab删除时遍历找到对应的tab,然后把当前激活的activeIndex设置到当前tab的下一个或上一个
methods:

 removeTab(target) {
      // 删除的是当前选中的页面
      if (this.activeIndex === target) {
        this.openTab.forEach((item, index) => {
          if (item.name == target) {
            let nextTab = item[index + 1] || item[index - 1];
            if (nextTab) {
              this.activeIndex = nextTab.name;
            }
          }
        });
      }
      var i = 0;
      this.openTab.forEach((item, index) => {
        if (item.name == target) {
          return (i = index);
        }
      });
      this.openTab.splice(i, 1);

      // 更新路由
      this.$router.push({ path: this.openTab[this.openTab.length - 1].name });
    },

    clickTab(tab) {
      this.activeIndex = tab.paneName;
      this.$router.push({ path: this.activeIndex });
    },



  watch: {
    $route(to, form) {
      //当路由更新进行tab切换
      var flag = false;
      // 当前页面菜单已打开,直接切换过去
      if (this.openTab) {
        for (let i = 0; i < this.openTab.length; i++) {
          if (
            to.path == this.openTab[i].name || to.path.includes(this.openTab[i].name)
          ) {
            //openTab中已存在?
            this.activeIndex = this.openTab[i].name;
            flag = true;
            break;
          }
        }
      }

      // 打开新的页面tab
      if (!flag) {
        let obj = {
          title: to.meta.title,
          name: to.path,
          closable: true,
          componentName: to.matched[1].components.default.name //路由只缓存到第1层,更深层的视图不考虑
        };
        this.activeIndex = to.path;
        this.openTab.push(obj);
      }
    },
  }

通过watch监测路由的变动对tab进行处理,也是遍历找到对应的tab进行切换,当路由切换时不仅route-view会进行改变,tab也会跟着更新。
注意当点击导航打开的一个新的路由时需要添加新的tab,同时需要从当前路由配置中拿出对应页面的组件名name存储到componentName中,这里拿取第一层是因为目前不考虑多级路由情况的。

以上就是本编文章的所有内容了,重点有建立tab和视图,实现删除功能,到最后的watch方式监听路边来切换tab,详细说明了实现过程,如果你觉得好的话可以关注我,共同努力,共同进步。我目前是坚持每月都会发布前端相关文章。感谢~

你可能感兴趣的:(Vue路由+Tab组件实现多页签功能)