下面是为 Pinia Store 增加关闭所有标签页、关闭其他标签页、关闭左侧标签页和关闭右侧标签页功能的完整实现:
const useTabStore = defineStore('tabs', {
state: () => ({
tabs: [], // 标签页数组
activeTab: '', // 当前激活的标签页
cachedViews: [] // 需要缓存的视图名称
}),
actions: {
// 添加标签页
addTab(route) {
// 检查标签页是否已存在
const exists = this.tabs.some(tab => tab.path === route.path);
if (!exists) {
this.tabs.push({
title: route.meta.title,
path: route.path,
name: route.name,
meta: route.meta
});
// 如果路由需要缓存,则添加到缓存列表
if (route.meta.keepAlive && !this.cachedViews.includes(route.name)) {
this.cachedViews.push(route.name);
}
}
// 设置当前激活的标签页
this.activeTab = route.path;
},
// 关闭标签页
closeTab(tab) {
// 从标签页列表中移除
this.tabs = this.tabs.filter(t => t.path !== tab.path);
// 如果关闭的是当前激活的标签页
if (this.activeTab === tab.path) {
// 激活最后一个标签页
const lastTab = this.tabs[this.tabs.length - 1];
if (lastTab) {
router.push(lastTab.path);
this.activeTab = lastTab.path;
} else {
// 如果没有标签页了,跳转到首页
router.push('/');
}
}
// 如果关闭的是需要缓存的标签页,从缓存中移除
if (tab.meta?.keepAlive) {
this.cachedViews = this.cachedViews.filter(name => name !== tab.name);
}
},
// 切换标签页
switchTab(tab) {
router.push(tab.path);
this.activeTab = tab.path;
},
// 关闭所有标签页
closeAllTabs() {
// 保留首页(如果存在)
const homeTab = this.tabs.find(tab => tab.path === '/');
// 清空标签页数组
this.tabs = [];
// 清空缓存
this.cachedViews = [];
// 如果首页存在,重新添加首页
if (homeTab) {
this.tabs.push(homeTab);
if (homeTab.meta.keepAlive) {
this.cachedViews.push(homeTab.name);
}
router.push('/');
this.activeTab = '/';
} else {
// 如果没有首页,跳转到首页
router.push('/');
this.addTab(router.currentRoute.value);
}
},
// 关闭其他标签页(保留当前页和首页)
closeOtherTabs() {
const currentTab = this.tabs.find(tab => tab.path === this.activeTab);
const homeTab = this.tabs.find(tab => tab.path === '/');
// 保留当前页和首页
const tabsToKeep = [];
if (homeTab) tabsToKeep.push(homeTab);
if (currentTab && currentTab.path !== '/') tabsToKeep.push(currentTab);
// 过滤掉不需要保留的标签页
const tabsToClose = this.tabs.filter(tab => !tabsToKeep.includes(tab));
// 更新标签页列表
this.tabs = tabsToKeep;
// 更新缓存列表
this.cachedViews = this.tabs
.filter(tab => tab.meta.keepAlive)
.map(tab => tab.name);
// 如果当前页被关闭了,跳转到首页
if (!currentTab || !tabsToKeep.includes(currentTab)) {
router.push('/');
this.activeTab = '/';
}
},
// 关闭左侧标签页
closeLeftTabs() {
const currentIndex = this.tabs.findIndex(tab => tab.path === this.activeTab);
if (currentIndex > 1) { // 左侧有标签页需要关闭
// 获取需要关闭的标签页
const tabsToClose = this.tabs.slice(0, currentIndex);
// 保留首页(如果首页在左侧)
const homeTab = this.tabs.find(tab => tab.path === '/');
if (homeTab && tabsToClose.includes(homeTab)) {
// 首页保留
this.tabs = [homeTab, ...this.tabs.slice(currentIndex)];
} else {
// 没有首页,直接保留右侧
this.tabs = this.tabs.slice(currentIndex);
}
// 更新缓存列表
this.cachedViews = this.tabs
.filter(tab => tab.meta.keepAlive)
.map(tab => tab.name);
}
},
// 关闭右侧标签页
closeRightTabs() {
const currentIndex = this.tabs.findIndex(tab => tab.path === this.activeTab);
if (currentIndex < this.tabs.length - 1) { // 右侧有标签页需要关闭
// 获取需要关闭的标签页
const tabsToClose = this.tabs.slice(currentIndex + 1);
// 保留首页(如果首页在右侧)
const homeTab = this.tabs.find(tab => tab.path === '/');
if (homeTab && tabsToClose.includes(homeTab)) {
// 首页保留
this.tabs = [...this.tabs.slice(0, currentIndex + 1), homeTab];
} else {
// 没有首页,直接保留左侧
this.tabs = this.tabs.slice(0, currentIndex + 1);
}
// 更新缓存列表
this.cachedViews = this.tabs
.filter(tab => tab.meta.keepAlive)
.map(tab => tab.name);
}
},
// 关闭除首页外的所有标签页
closeAllExceptHome() {
const homeTab = this.tabs.find(tab => tab.path === '/');
if (homeTab) {
// 只保留首页
this.tabs = [homeTab];
this.cachedViews = homeTab.meta.keepAlive ? [homeTab.name] : [];
if (this.activeTab !== '/') {
router.push('/');
this.activeTab = '/';
}
} else {
// 如果首页不存在,则跳转到首页并添加
router.push('/');
this.addTab(router.currentRoute.value);
}
}
}
});