1. 程式人生 > 實用技巧 >Vue+elementui點選導航欄新增相應的tabs

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