tabsView.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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'];
  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(
  38. (item) => item.fullPath === activeKey || !pathList.includes(item.fullPath),
  39. );
  40. }
  41. export const useTabsViewStore = defineStore({
  42. id: 'app-tabs-view',
  43. state: (): ITabsViewState => ({
  44. tabsList: [],
  45. }),
  46. getters: {
  47. getTabList(): RouteLocationNormalized[] {
  48. return this.tabsList;
  49. },
  50. },
  51. actions: {
  52. //查找设置缓存name
  53. findKeepAliveNames(list) {
  54. const names = [];
  55. list.forEach((item) => {
  56. if (item.meta?.keepAlive) {
  57. names.push(item.name);
  58. }
  59. });
  60. return names;
  61. },
  62. //从缓存中删除关闭的路由
  63. delKeepAliveNames(list) {
  64. const asyncRouteStore = useAsyncRouteStore();
  65. const names = this.findKeepAliveNames(list);
  66. asyncRouteStore.removeKeepAliveComponents(names);
  67. },
  68. // 初始化标签页
  69. initTabs(routes) {
  70. this.tabsList = routes;
  71. },
  72. // 添加标签页
  73. addTabs(route): boolean {
  74. if (whiteList.includes(route.name)) return false;
  75. const isExists = this.tabsList.some((item) => item.fullPath == route.fullPath);
  76. if (!isExists) {
  77. this.tabsList.push(route);
  78. } else {
  79. //如果是存在的路由,则刷新信息
  80. const _index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
  81. this.tabsList[_index] = route;
  82. }
  83. return true;
  84. },
  85. // 关闭左侧
  86. closeLeftTabs(route, activeKey) {
  87. const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
  88. if (index > 0) {
  89. const leftTabs = this.tabsList.slice(0, index);
  90. const newLeftTabs = filterCurrentRoute(leftTabs, activeKey);
  91. this.delKeepAliveNames(newLeftTabs);
  92. this.tabsList = filterNewTabs(newLeftTabs, this.tabsList, activeKey);
  93. }
  94. },
  95. // 关闭右侧
  96. closeRightTabs(route, activeKey) {
  97. const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
  98. if (index >= 0 && index < this.tabsList.length - 1) {
  99. const rightTabs = this.tabsList.slice(index + 1, this.tabsList.length);
  100. const newRightTabs = filterCurrentRoute(rightTabs, activeKey);
  101. this.delKeepAliveNames(newRightTabs);
  102. this.tabsList = filterNewTabs(newRightTabs, this.tabsList, activeKey);
  103. }
  104. },
  105. // 关闭其他
  106. closeOtherTabs(route, activeKey) {
  107. const newTabsList = this.tabsList.filter(
  108. (item) =>
  109. ([route.value.fullPath, activeKey].includes(item.fullPath) || item?.meta?.affix) ?? false,
  110. );
  111. this.delKeepAliveNames(newTabsList);
  112. this.tabsList = newTabsList;
  113. },
  114. // 关闭当前页
  115. closeCurrentTab(route) {
  116. const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
  117. if (index != -1) {
  118. this.delKeepAliveNames([this.tabsList[index]]);
  119. this.tabsList.splice(index, 1);
  120. }
  121. },
  122. // 关闭全部
  123. closeAllTabs() {
  124. this.delKeepAliveNames(this.tabsList);
  125. this.tabsList = retainAffixRoute(this.tabsList);
  126. },
  127. // 设置标题
  128. async setTabTitle(title: string, route: RouteLocationNormalized) {
  129. this.tabsList.forEach((item) => {
  130. if (item.fullPath === route.fullPath) {
  131. item.meta.title = title;
  132. }
  133. });
  134. storage.set(TABS_ROUTES, JSON.stringify(this.tabsList));
  135. },
  136. // 设置状态
  137. async setTabState(params, route: RouteLocationNormalized) {
  138. this.tabsList.forEach((item) => {
  139. if (item.fullPath === route.fullPath) {
  140. item.meta = {
  141. ...item.meta,
  142. ...params,
  143. };
  144. }
  145. });
  146. storage.set(TABS_ROUTES, JSON.stringify(this.tabsList));
  147. },
  148. },
  149. });