微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Vue+elementui点击导航栏添加相应的tabs

参考:https://blog.csdn.net/hjx154954264/article/details/104799141/

一、前期准备工作

1.在index.js里正常导入路由

 

 

//这里的Meta的comp设置,加上单引号为字符串,如果设置为路由,后续会把路由缓存进sessionStorage,缓存里面的数据是json格式, component 是一个vue文件,所以没办法解析,会报错

 

2.写导航菜单navmenu(开启路由模式)

 

 

 3.写tab标签

 

 

 

 

 

     tabs的content用组件展示

    (1)导入组件

     

 

 

     (2)  

      

 

 

 

 

 二、动态添加tabs

 1  watch: {
 2     $route: function (to) {
 3       //监听路由的变化,动态生成tabs
 4       console.log(to);
 5       let flag = true; //判断是否需要新增页面
 6       const path = to.path;
 7       console.log(Object.keys(to.Meta).length)
 8       if (Object.keys(to.Meta).length != 0) {
 9         for (let i = 0; i < this.$refs.tabs.length; i++) {
10           if (i != 0) {
11             //首页不判断 如果页面已存在,则直接定位当页面,否则新增tab页面
12             if (this.$refs.tabs[i].label == to.Meta.name) {
13               this.activeTab = this.$refs.tabs[i].name; //定位到已打开页面
14               flag = false;
15               break;
16             }
17           }
18         }
19         //新增页面
20         if (flag) {
21           //获得路由元数据的name和组件名
22           const thisName = to.Meta.name; //在index.js中定义的Meta
23           const thisComp = to.Meta.comp;
24           //对tabs的当前激活下标和tabs数量进行自加
25           let newActiveIndex = ++this.tabIndex + "";
26           //动态双向追加tabs
27           this.tabsItem.push({
28             title: thisName,
29             name: String(newActiveIndex),
30             closable: true,
31             ref: "tabs",
32             content: thisComp,
33           });
34           this.activeTab = newActiveIndex;
35           /*
36            * 当添加tabs的时候,把当前tabs的name作为key,path作为value存入tabsPath数组中
37            * ///后面需要得到当前tabs的时候可以通过当前tabs的name获得path
38            * */
39           if (this.tabsPath.indexOf(path) == -1) {
40             this.tabsPath.push({
41               name: newActiveIndex,
42               path: path,
43             });
44           }
45         }
46       }
47     },
48   },

三、用sessionstorage保存tabs(否则一刷新标签页就恢复原样,只有首页

 mounted() {
    /*
     * 监听页面刷新事件
     * 页面刷新前 需要保存当前打开的tabs的位置,刷新后按刷新前的顺序展示
     * 使用js的sessionStorage保存刷新页面前的数据
     * */
    window.addEventListener("beforeunload", (e) => {
      sessionStorage.setItem(
        "tabsItem",
        JSON.stringify({
          currTabsItem: this.tabsItem.filter((item) => item.name !== "1"),
          currTabsPath: this.tabsPath.filter((item) => item.name !== "1"),
          currActiveTabs: this.activeTab,
          currIndex: this.tabIndex,
        })
      );
    });
  },
  created() {
    /*
     * 使用js的sessionStorage读取刷新前的数据,并按刷新前的tabs顺序重新生成tabs
     * */
    const sessionTabs = JSON.parse(sessionStorage.getItem("tabsItem"));
    if (
      sessionTabs.currTabsItem.length != 0 &&
      sessionTabs.currTabsPath.length != 0
    ) {
      for (let i = 0; i < sessionTabs.currTabsItem.length; i++) {
        this.tabsItem.push({
          title: sessionTabs.currTabsItem[i].title,
          name: sessionTabs.currTabsItem[i].name,
          closable: true,
          ref: sessionTabs.currTabsItem[i].ref,
          content: sessionTabs.currTabsItem[i].content,
          //这里不要把路由缓存进sessionStorage,因为缓存里面的数据是json格式, component 是一个vue文件,所以没办法解析,会报错(此处我的content已经改成了字符串了)
        });
      }
      for (let j = 0; j < sessionTabs.currTabsPath.length; j++) {
        this.tabsPath.push({
          name: sessionTabs.currTabsPath[j].name,
          path: sessionTabs.currTabsPath[j].path,
        });
      }
      this.activeTab = sessionTabs.currActiveTabs;
      this.tabIndex = sessionTabs.currIndex;
      //避免强制修改url 出现浏览器的url输入框的路径和当前tabs选中的路由路径不匹配
      const activePath = this.tabsPath.filter(
        (item) => item.name == this.activeTab
      );
      this.$router.push({
        path: activePath[0].path,
      });
      
    } 
  },

四、实现删除标签

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,
      });
    },

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐