醋醋百科网

Good Luck To You!

Pinia Store 多标签页管理功能扩展



下面是为 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` 只缓存当前存在的页面

这些功能实现了完整的多标签页管理,包括各种关闭操作,适合在后台管理系统框架中使用。

以上内容为自己项目 中实现的方式!
分享出来!

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言