在vue單頁面應用中,當點選導航選單時會切換路由,一般是在中間的router-view
路由檢視中直接顯示對應路由的頁面元件,那麼本編就介紹一下如何使用vue路由配合tab
元件實現多頁籤功能,開啟一個新的選單路由時變成彈出一個新的tab頁籤,並且隨時可以切換到之前的頁面,保留之前的元件狀態。
當前開啟的tab需要在data
中以一個陣列的方式維護(openTab)
,預設顯示首頁
main.vue:
openTab: [
{
title: "首頁",
name: "/Index", //路由
closable: false, //首頁不可關閉
componentName: "index" //元件名稱用於keepalive快取
}
],
componentName
是對應tab中頁面元件的name
值,所以每一個元件都必須設定自己的name值。
下面看template
如何實現,首先加入elementUI
的tab
元件:
<div
id="main-home"
>
<el-tabs
@tab-remove="removeTab"
v-model="activeIndex"
type="card"
class="main-tab"
@tab-click="clickTab"
>
<el-tab-pane
:key="item.name"
v-for="item in openTab"
:label="item.title"
:name="item.name"
:closable="item.closable"
></el-tab-pane>
</el-tabs>
<div class="view-container">
<keep-alive :include="openTab.map(i => i.componentName)">
<router-view v-if="isRouterAlive"></router-view>
</keep-alive>
</div>
</div>
注意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,詳細說明了實現過程,如果你覺得好的話可以關注我,共同努力,共同進步。我目前是堅持每月都會發布前端相關文章。感謝~