tabsView.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { defineStore } from 'pinia';
  2. import { RouteLocationNormalized } from 'vue-router';
  3. import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
  4. import { storage } from '@/utils/Storage';
  5. import { TABS_ROUTES } from '@/store/mutation-types';
  6. // 不需要出现在标签页中的路由
  7. const whiteList = ['Redirect', 'Login', 'StayTune'];
  8. export type RouteItem = Partial<RouteLocationNormalized> & {
  9. fullPath: string;
  10. path: string;
  11. name: string;
  12. hash: string;
  13. meta: object;
  14. params: object;
  15. query: object;
  16. };
  17. export type ITabsViewState = {
  18. tabsList: RouteItem[]; // 标签页
  19. };
  20. //过滤当前路由
  21. function filterCurrentRoute(list: any[], activeKey) {
  22. return list.filter((item) => item.fullPath != activeKey);
  23. }
  24. //保留固定路由
  25. function retainAffixRoute(list: any[]) {
  26. return list.filter((item) => item?.meta?.affix ?? false);
  27. }
  28. //筛序最新的
  29. function filterNewTabs(sliceTabs: any[], tabsList: any[], activeKey = '') {
  30. const pathList: string[] = [];
  31. for (const item of sliceTabs) {
  32. const affix = item?.meta?.affix ?? false;
  33. if (!affix) {
  34. pathList.push(item.fullPath);
  35. }
  36. }
  37. return tabsList.filter((item) => item.fullPath === activeKey || !pathList.includes(item.fullPath));
  38. }
  39. export const useTabsViewStore = defineStore({
  40. id: 'app-tabs-view',
  41. state: (): ITabsViewState => ({
  42. tabsList: [],
  43. }),
  44. getters: {
  45. getTabList(): RouteLocationNormalized[] {
  46. return this.tabsList;
  47. },
  48. },
  49. actions: {
  50. //查找设置缓存name
  51. findKeepAliveNames(list) {
  52. const names = [];
  53. list.forEach((item) => {
  54. if (item.meta?.keepAlive) {
  55. names.push(item.name);
  56. }
  57. });
  58. return names;
  59. },
  60. //从缓存中删除关闭的路由
  61. delKeepAliveNames(list) {
  62. const asyncRouteStore = useAsyncRouteStore();
  63. const names = this.findKeepAliveNames(list);
  64. asyncRouteStore.removeKeepAliveComponents(names);
  65. },
  66. // 初始化标签页
  67. initTabs(routes) {
  68. this.tabsList = routes;
  69. },
  70. // 添加标签页
  71. addTabs(route): boolean {
  72. if (whiteList.includes(route.name)) return false;
  73. const isExists = this.tabsList.some((item) => item.fullPath == route.fullPath);
  74. if (!isExists) {
  75. this.tabsList.push(route);
  76. } else {
  77. //如果是存在的路由,则刷新信息
  78. const _index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
  79. this.tabsList[_index] = route;
  80. }
  81. return true;
  82. },
  83. // 关闭左侧
  84. closeLeftTabs(route, activeKey) {
  85. const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
  86. if (index > 0) {
  87. const leftTabs = this.tabsList.slice(0, index);
  88. const newLeftTabs = filterCurrentRoute(leftTabs, activeKey);
  89. this.delKeepAliveNames(newLeftTabs);
  90. this.tabsList = filterNewTabs(newLeftTabs, this.tabsList, activeKey);
  91. }
  92. },
  93. // 关闭右侧
  94. closeRightTabs(route, activeKey) {
  95. const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
  96. if (index >= 0 && index < this.tabsList.length - 1) {
  97. const rightTabs = this.tabsList.slice(index + 1, this.tabsList.length);
  98. const newRightTabs = filterCurrentRoute(rightTabs, activeKey);
  99. this.delKeepAliveNames(newRightTabs);
  100. this.tabsList = filterNewTabs(newRightTabs, this.tabsList, activeKey);
  101. }
  102. },
  103. // 关闭其他
  104. closeOtherTabs(route, activeKey) {
  105. const newTabsList = this.tabsList.filter(
  106. (item) => ([route.value.fullPath, activeKey].includes(item.fullPath) || item?.meta?.affix) ?? false,
  107. );
  108. this.delKeepAliveNames(newTabsList);
  109. this.tabsList = newTabsList;
  110. },
  111. // 关闭当前页
  112. closeCurrentTab(route) {
  113. const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
  114. if (index != -1) {
  115. this.delKeepAliveNames([this.tabsList[index]]);
  116. this.tabsList.splice(index, 1);
  117. }
  118. },
  119. // 关闭全部
  120. closeAllTabs() {
  121. this.delKeepAliveNames(this.tabsList);
  122. this.tabsList = retainAffixRoute(this.tabsList);
  123. },
  124. // 设置标题
  125. async setTabTitle(title: string, route: RouteLocationNormalized) {
  126. this.tabsList.forEach((item) => {
  127. if (item.fullPath === route.fullPath) {
  128. item.meta.title = title;
  129. }
  130. });
  131. storage.set(TABS_ROUTES, JSON.stringify(this.tabsList));
  132. },
  133. // 设置状态
  134. async setTabState(params, route: RouteLocationNormalized) {
  135. this.tabsList.forEach((item) => {
  136. if (item.fullPath === route.fullPath) {
  137. item.meta = {
  138. ...item.meta,
  139. ...params,
  140. };
  141. }
  142. });
  143. storage.set(TABS_ROUTES, JSON.stringify(this.tabsList));
  144. },
  145. },
  146. });