下面是为 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);
}
}
}
});
使用示例
在 Vue 组件中调用这些方法:
// 在组件中使用
import { useTabStore } from '@/stores/tabs';
const tabStore = useTabStore();
// 关闭所有标签页
tabStore.closeAllTabs();
// 关闭其他标签页
tabStore.closeOtherTabs();
// 关闭左侧标签页
tabStore.closeLeftTabs();
// 关闭右侧标签页
tabStore.closeRightTabs();
// 关闭除首页外的所有标签页
tabStore.closeAllExceptHome();
功能说明
1. closeAllTabs():
- 关闭所有标签页
- 保留首页(如果存在)
- 如果没有首页,则跳转并添加首页
2. closeOtherTabs():
- 保留当前激活的标签页和首页
- 关闭其他所有标签页
- 如果当前页就是首页,则只保留首页
3. closeLeftTabs():
- 关闭当前激活标签页左侧的所有标签页
- 保留首页(如果首页在左侧)
- 只处理左侧有标签页的情况
4. closeRightTabs():
- 关闭当前激活标签页右侧的所有标签页
- 保留首页(如果首页在右侧)
- 只处理右侧有标签页的情况
5. closeAllExceptHome():
- 关闭除首页外的所有标签页
- 只保留首页
- 如果没有首页,则跳转并添加首页
缓存处理
所有关闭操作都会同步更新 `cachedViews` 数组:
- 只保留当前标签页列表中需要缓存的页面
- 被关闭的标签页对应的缓存会被移除
- 确保 `keep-alive` 只缓存当前存在的页面
这些功能实现了完整的多标签页管理,包括各种关闭操作,适合在后台管理系统框架中使用。
以上内容为自己项目 中实现的方式!
分享出来!