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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM