Vue+elementui點選導航欄新增相應的tabs
阿新 • • 發佈:2020-08-26
參考: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,
});
},