vue-stack-tabs 0.1.51 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +717 -3
  2. package/dist/index.d.ts +3 -0
  3. package/dist/src/lib/StackTabs.vue.d.ts +33 -161
  4. package/dist/src/lib/components/ContextMenu/ContextMenuItem.vue.d.ts +6 -6
  5. package/dist/src/lib/components/ContextMenu/index.vue.d.ts +14 -14
  6. package/dist/src/lib/components/PageLoading.vue.d.ts +5 -5
  7. package/dist/src/lib/components/TabHeader/TabHeaderButton.vue.d.ts +24 -15
  8. package/dist/src/lib/components/TabHeader/TabHeaderItem.vue.d.ts +10 -8
  9. package/dist/src/lib/components/TabHeader/TabHeaderScroll.vue.d.ts +31 -13
  10. package/dist/src/lib/components/TabHeader/index.vue.d.ts +172 -20
  11. package/dist/src/lib/hooks/tabPanel/evict.d.ts +24 -0
  12. package/dist/src/lib/hooks/tabPanel/evict.spec.d.ts +1 -0
  13. package/dist/src/lib/hooks/tabPanel/scroll.d.ts +8 -0
  14. package/dist/src/lib/hooks/tabPanel/session.d.ts +9 -0
  15. package/dist/src/lib/hooks/tabPanel/state.d.ts +77 -0
  16. package/dist/src/lib/hooks/useContextMenu.d.ts +6 -1
  17. package/dist/src/lib/hooks/useTabActions.d.ts +68 -0
  18. package/dist/src/lib/hooks/{useTabMitt.d.ts → useTabEventBus.d.ts} +4 -3
  19. package/dist/src/lib/hooks/useTabLoading.d.ts +6 -0
  20. package/dist/src/lib/hooks/{useTabpanel.d.ts → useTabPanel.d.ts} +20 -14
  21. package/dist/src/lib/hooks/useTabPanel.spec.d.ts +1 -0
  22. package/dist/src/lib/hooks/useTabRouter.d.ts +14 -5
  23. package/dist/src/lib/i18n/index.d.ts +1 -1
  24. package/dist/src/lib/i18n/lang/en.d.ts +1 -0
  25. package/dist/src/lib/i18n/lang/zh-CN.d.ts +1 -0
  26. package/dist/src/lib/index.d.ts +5 -4
  27. package/dist/src/lib/model/TabModel.d.ts +20 -3
  28. package/dist/src/lib/model/TabModel.spec.d.ts +1 -0
  29. package/dist/src/lib/utils/iframeBridge.d.ts +31 -0
  30. package/dist/src/lib/utils/iframeBridge.spec.d.ts +1 -0
  31. package/dist/src/lib/utils/scrollUtils.d.ts +28 -0
  32. package/dist/src/lib/utils/tabInfoEncoder.d.ts +19 -0
  33. package/dist/src/lib/utils/tabInfoEncoder.spec.d.ts +1 -0
  34. package/dist/src/lib/utils/urlParser.d.ts +19 -0
  35. package/dist/src/lib/utils/urlParser.spec.d.ts +1 -0
  36. package/dist/src/lib/versionLogger.d.ts +2 -0
  37. package/dist/style.css +1 -1
  38. package/dist/vue-stack-tabs.css +1 -0
  39. package/dist/vue-stack-tabs.es.js +1795 -1679
  40. package/dist/vue-stack-tabs.umd.js +1 -5
  41. package/package.json +76 -39
  42. package/src/lib/StackTabs.vue +222 -47
  43. package/src/lib/assets/image/open.svg +1 -0
  44. package/src/lib/assets/style/common/var.scss +1 -1
  45. package/src/lib/assets/style/icon.scss +6 -0
  46. package/src/lib/assets/style/stackTab.scss +46 -3
  47. package/src/lib/assets/style/transition.scss +63 -62
  48. package/src/lib/components/ContextMenu/ContextMenuItem.vue +7 -0
  49. package/src/lib/components/ContextMenu/index.vue +50 -38
  50. package/src/lib/components/PageLoading.vue +30 -10
  51. package/src/lib/components/TabHeader/TabHeaderButton.vue +12 -3
  52. package/src/lib/components/TabHeader/TabHeaderItem.vue +31 -27
  53. package/src/lib/components/TabHeader/TabHeaderScroll.vue +83 -77
  54. package/src/lib/components/TabHeader/index.vue +45 -40
  55. package/src/lib/hooks/tabPanel/evict.spec.ts +85 -0
  56. package/src/lib/hooks/tabPanel/evict.ts +57 -0
  57. package/src/lib/hooks/tabPanel/scroll.ts +52 -0
  58. package/src/lib/hooks/tabPanel/session.ts +33 -0
  59. package/src/lib/hooks/tabPanel/state.ts +52 -0
  60. package/src/lib/hooks/useContextMenu.ts +22 -20
  61. package/src/lib/hooks/useTabActions.ts +148 -0
  62. package/src/lib/hooks/useTabEventBus.ts +31 -0
  63. package/src/lib/hooks/useTabLoading.ts +12 -4
  64. package/src/lib/hooks/useTabPanel.spec.ts +34 -0
  65. package/src/lib/hooks/useTabPanel.tsx +546 -0
  66. package/src/lib/hooks/useTabRouter.ts +114 -103
  67. package/src/lib/i18n/index.ts +14 -18
  68. package/src/lib/i18n/lang/en.ts +2 -1
  69. package/src/lib/i18n/lang/zh-CN.ts +2 -1
  70. package/src/lib/iframe.vue +6 -0
  71. package/src/lib/index.ts +27 -8
  72. package/src/lib/model/TabModel.spec.ts +40 -0
  73. package/src/lib/model/TabModel.ts +22 -9
  74. package/src/lib/nuxt/module.d.ts +19 -0
  75. package/src/lib/nuxt/module.ts +34 -0
  76. package/src/lib/nuxt/runtime/plugin.client.ts +11 -0
  77. package/src/lib/utils/iframeBridge.spec.ts +37 -0
  78. package/src/lib/utils/iframeBridge.ts +52 -0
  79. package/src/lib/utils/{TabScrollHelper.ts → scrollUtils.ts} +23 -29
  80. package/src/lib/utils/tabInfoEncoder.spec.ts +42 -0
  81. package/src/lib/utils/tabInfoEncoder.ts +65 -0
  82. package/src/lib/utils/urlParser.spec.ts +45 -0
  83. package/src/lib/utils/urlParser.ts +42 -0
  84. package/src/lib/{banner.ts → versionLogger.ts} +4 -5
  85. package/dist/src/lib/banner.d.ts +0 -2
  86. package/dist/src/lib/hooks/useStackTab.d.ts +0 -11
  87. package/dist/src/lib/utils/TabIdHelper.d.ts +0 -11
  88. package/dist/src/lib/utils/TabScrollHelper.d.ts +0 -33
  89. package/dist/src/lib/utils/UriHelper.d.ts +0 -4
  90. package/src/lib/hooks/useStackTab.ts +0 -119
  91. package/src/lib/hooks/useTabMitt.ts +0 -30
  92. package/src/lib/hooks/useTabpanel.tsx +0 -708
  93. package/src/lib/utils/TabIdHelper.ts +0 -70
  94. package/src/lib/utils/UriHelper.ts +0 -22
@@ -1,708 +0,0 @@
1
- import type { ITabBase, ITabData, ITabItem, ITabPage } from '../model/TabModel'
2
- import {
3
- defineComponent,
4
- nextTick,
5
- onActivated,
6
- onDeactivated,
7
- onMounted,
8
- onUnmounted,
9
- ref,
10
- unref
11
- } from 'vue'
12
- import type { DefineComponent, VNode } from 'vue'
13
- import { useRouter } from 'vue-router'
14
- import type { RouteLocationNormalizedLoaded } from 'vue-router'
15
- import { ulid } from 'ulid'
16
- import { encodeTabInfo, createPageId, decodeTabInfo } from '../utils/TabIdHelper'
17
- import { defu } from 'defu'
18
- import { Stack } from '../model/TabModel'
19
- import { uriDecode } from '../utils/UriHelper'
20
- import PageLoading from '../components/PageLoading.vue'
21
- import { MittType, useEmitter } from './useTabMitt'
22
- import { useI18n } from 'vue-i18n-lite'
23
-
24
-
25
- const tabs = ref<ITabItem[]>([])
26
- const defaultTabs: ITabItem[] = []
27
- // cache
28
- const caches = ref<string[]>([])
29
- // Dynamic components
30
- const components = new Map<string, any>()
31
- const deletableCache = new Set<string>()
32
- const deletableTab = new Set<string>()
33
- const pageShown = ref<boolean>(true)
34
- const SESSION_TAB_NAME = 'stacktab-active-tab'
35
- const pageScroller = new Map<string, Map<string, any>>()
36
- const initialed = ref<boolean>(false)
37
- let max = 0
38
- let scrollbar = false
39
- let sessionPrefix = ''
40
- export default () => {
41
- const router = useRouter()
42
- const emitter = useEmitter()
43
- const { t } = useI18n()
44
- const size = (): number => {
45
- return tabs.value.length
46
- }
47
- /**
48
- * Init the Tab list
49
- */
50
- const initial = (staticTabs: ITabData[]) => {
51
- // add default tabs
52
- // defaultTabs.splice(0)
53
- // caches.value.splice(0)
54
- // deletableCache.clear()
55
- // deletableTab.clear()
56
- // components.clear()
57
- for (const item of staticTabs) {
58
- // const id = ulid()
59
- const fullItem = defu(item, { id: ulid(), refreshable: true, closable: true, iframe: false })
60
- const __tab = encodeTabInfo(fullItem)
61
- const uri = uriDecode(fullItem.path)
62
- const config = defu(fullItem, {
63
- closable: true,
64
- refreshable: true,
65
- iframe: false
66
- })
67
- const cacheName = createPageId(fullItem.id, uri.path, uri.query)
68
- const page: ITabPage = {
69
- id: cacheName,
70
- tabId: fullItem.id,
71
- path: uri.path,
72
- query: defu(uri.query, { __tab })
73
- }
74
- const pages = new Stack<ITabPage>()
75
- pages.push(page)
76
- const tab: ITabItem = {
77
- id: fullItem.id,
78
- title: config.title,
79
- closable: config.closable,
80
- refreshable: config.refreshable,
81
- iframe: config.iframe,
82
- active: false,
83
- pages
84
- }
85
-
86
- caches.value.push(cacheName)
87
-
88
- defaultTabs.push(tab)
89
- tabs.value.push({ ...tab })
90
- }
91
-
92
- // add temp tab from session
93
- const tempTab = window.sessionStorage.getItem(sessionPrefix+SESSION_TAB_NAME)
94
- if (tempTab !== null && tempTab !== undefined) {
95
- // const tempItems = JSON.parse(window.sessionStorage.getItem('tabItems')!)
96
- const temp = JSON.parse(tempTab, (k, v) => {
97
- if (k === 'pages') {
98
- return new Stack<ITabPage>(v)
99
- } else {
100
- return v
101
- }
102
- })
103
- // const temp = defu({ pages: new Stack<ITabPage>() }, tempItems) as ITabItem
104
- let hasTab = false
105
- for (const tab of tabs.value) {
106
- if (tab.id === temp.id) {
107
- hasTab = true
108
- break
109
- }
110
- }
111
- if (!hasTab) {
112
- tabs.value.push(temp)
113
- }
114
- }
115
- initialed.value = true
116
- }
117
- const hasTab = (id: string) => {
118
- for (const tab of tabs.value) {
119
- if (tab.id === id) {
120
- return true
121
- }
122
- }
123
- return false
124
- }
125
- const canAddTab = () => {
126
- return max <= 0 || (max > 0 && max > tabs.value.length)
127
- }
128
- const addTab = (tab: ITabItem) => {
129
- return new Promise((resolve) => {
130
- tabs.value.push(tab)
131
- resolve(true)
132
- })
133
- }
134
- const getTab = (id: string) => {
135
- for (const tab of tabs.value) {
136
- if (tab.id === id) {
137
- return tab
138
- }
139
- }
140
- return null
141
- }
142
- const addPage = (route: RouteLocationNormalizedLoaded, component: VNode): DefineComponent => {
143
- let cacheComponent: DefineComponent
144
- let tabInfo: ITabBase
145
- if (route.query.__tab) {
146
- tabInfo = decodeTabInfo(route.query.__tab as string)
147
- } else {
148
- tabInfo = {
149
- id: ulid(),
150
- title: t('VueStackTab.undefined'),
151
- closable: true,
152
- refreshable: true,
153
- iframe: false
154
- }
155
- route.query.__tab = encodeTabInfo(tabInfo)
156
- }
157
-
158
- if (deletableTab.has(tabInfo.id!) || !component) {
159
- return
160
- }
161
-
162
- /**
163
- * if using nginx as web server, it will add '/' at the end of url.
164
- *
165
- */
166
- const matchPath = route.matched[route.matched.length - 1].path
167
- const tmpPath = route.path.endsWith('/')
168
- ? route.path.substring(0, route.path.length - 1)
169
- : route.path
170
-
171
- const cacheName = createPageId(
172
- tabInfo.id!,
173
- matchPath === tmpPath ? tmpPath : route.path,
174
- route.query.valueOf()
175
- )
176
- if(deletableCache.has(cacheName)) {
177
- return components.get(cacheName)!
178
- }
179
- const src = route.query.__src
180
- // 增加tab
181
- let activeTab: ITabItem | null = null
182
- for (const tab of unref(tabs)) {
183
- tab.active = false
184
- if (tab.id === tabInfo.id) {
185
- activeTab = tab as ITabItem
186
- }
187
- }
188
- const page: ITabPage = {
189
- id: cacheName,
190
- tabId: tabInfo.id!,
191
- path: route.path,
192
- query: route.query as Record<string, string>
193
- }
194
-
195
- if (activeTab === null) {
196
- const pages = new Stack<ITabPage>()
197
- pages.push(page)
198
- activeTab = {
199
- id: tabInfo.id!,
200
- title: tabInfo.title,
201
- closable: tabInfo.closable!,
202
- refreshable: tabInfo.refreshable!,
203
- iframe: tabInfo.iframe!,
204
- url: decodeURIComponent(src as string),
205
- active: true,
206
- pages
207
- }
208
- addTab(activeTab).then(() => {
209
- emitter.emit(MittType.TAB_ACTIVE, { id: tabInfo.id!, isRoute: false })
210
- })
211
- } else {
212
- activeTab.active = true
213
- if (activeTab.pages.isEmpty() || activeTab.pages.peek()!.id !== page.id) {
214
- activeTab.pages.push(page)
215
- }
216
- }
217
- updateSession(activeTab)
218
- // const cacheSet = new Set(caches.value)
219
- if (components.has(cacheName)) {
220
- cacheComponent = components.get(cacheName)!
221
- } else {
222
- // 增加控件
223
- cacheComponent = defineComponent({
224
- name: cacheName!,
225
- components: {
226
- DynamicComponent: component
227
- },
228
- emits: {
229
- onLoaded: null
230
- },
231
- setup(props, context) {
232
- onMounted(() => {
233
- context.emit('onLoaded')
234
- addPageScroller(cacheName, '.cache-page-wrapper')
235
- })
236
- onDeactivated(() => {
237
- saveScroller(cacheName)
238
- })
239
- onActivated(() => {
240
- context.emit('onLoaded')
241
- restoreScroller(cacheName)
242
- console.log(pageScroller.get(cacheName))
243
- removeDeletableCache()
244
- deletableTab.clear()
245
- component.props = null
246
- })
247
- onUnmounted(() => {
248
- console.log('on unMounted', cacheName)
249
- removeScroller(cacheName)
250
- // setTimeout(() => {
251
- // 刷新时重置路由
252
- // pageShown.value = true
253
- // }, 500)
254
- })
255
- return () => (
256
- <div
257
- class="cache-page-wrapper"
258
- id={'W-' + tabInfo.id}
259
- style={[scrollbar ? 'overflow:auto' : 'overflow:hidden']}
260
- >
261
- <dynamic-component tId={tabInfo.id} pId={cacheName} />
262
- <PageLoading tId={tabInfo.id!} />
263
- </div>
264
- )
265
- }
266
- })
267
- components.set(cacheName, cacheComponent)
268
-
269
- //
270
- }
271
-
272
- // 加入缓存
273
- // const cacheSet = new Set(caches.value)
274
- // if (routerAlive.value) {
275
- // if (!cacheSet.has(cacheName)) {
276
- // caches.value.push(cacheName)
277
- // }
278
- // }
279
- addCache(cacheName)
280
- return cacheComponent
281
- }
282
- const restoreScroller = (pageId: string) => {
283
- const scroller = pageScroller.get(pageId)
284
- if (scroller) {
285
- for (const key of scroller.keys()) {
286
- if (document.querySelector(key)) {
287
- const result = scroller.get(key)!
288
- document.querySelector(key)!.scrollTop = result.top
289
- document.querySelector(key)!.scrollLeft = result.left
290
- }
291
- }
292
- }
293
- }
294
- const saveScroller = (pageId: string) => {
295
- const scroller = pageScroller.get(pageId)
296
- if (scroller) {
297
- for (const key of scroller.keys()) {
298
- const result = {
299
- top: document.querySelector(key)?.scrollTop ?? 0,
300
- left: document.querySelector(key)?.scrollLeft ?? 0
301
- }
302
- scroller.set(key, result)
303
- }
304
- }
305
- }
306
-
307
- const removeScroller = (pageId: string) => {
308
- const scroller = pageScroller.get(pageId)!
309
- if (scroller) {
310
- scroller.clear()
311
- pageScroller.delete(pageId)
312
- }
313
- }
314
- const addPageScroller = (pageId: string, ...scrollerIds: string[]) => {
315
- if (!pageScroller.has(pageId)) {
316
- pageScroller.set(pageId, new Map<string, number>())
317
- }
318
- const scroller = pageScroller.get(pageId)!
319
- for (const sId of scrollerIds) {
320
- scroller.set(sId, { top: 0, left: 0 })
321
- }
322
- }
323
- // use new url for renwTab like refresh tab
324
- const renewTab = (tab: ITabData) => {
325
- const currentTab = getTab(tab.id!)
326
- for (const item of currentTab!.pages.list()) {
327
- // removeComponent(item.id)
328
- markDeletableCache(item.id)
329
- }
330
- removeDeletableCache()
331
- currentTab!.pages.clear()
332
- }
333
- /**
334
- * if id is null , then remove all tab that deleted is true
335
- * @param id
336
- */
337
- const removeTab = (id: string): string => {
338
- let activeTabId = ''
339
- const currentTab = getTab(id)
340
- for (let i = tabs.value.length - 1; i >= 0; i--) {
341
- if (id === unref(tabs)[i].id) {
342
- //if it's not closable then return
343
- if (!unref(tabs)[i].closable) {
344
- return id
345
- }
346
- for (const item of unref(tabs)[i].pages.list()) {
347
- // removeComponent(item.id)
348
- markDeletableCache(item.id)
349
- deletableTab.add(unref(tabs)[i].id)
350
- }
351
- unref(tabs)[i].pages.clear()
352
- if (tabs.value.length > 1 && unref(tabs)[i].active) {
353
- if (i === 0) {
354
- activeTabId = unref(tabs)[i + 1].id
355
- } else {
356
- activeTabId = unref(tabs)[i - 1].id
357
- }
358
- }
359
- unref(tabs).splice(i, 1)
360
-
361
- break
362
- }
363
- }
364
-
365
- if (activeTabId !== '') {
366
- emitter.emit(MittType.TAB_ACTIVE, { id: activeTabId })
367
- // active(activeTabId)
368
- }
369
- // if remove inactive tab,then we need remove the cache manually.
370
-
371
- if (!currentTab?.active) {
372
- removeDeletableCache()
373
- deletableTab.clear()
374
- }
375
-
376
- return activeTabId
377
- }
378
-
379
- const removeAllTabs = () => {
380
- const uTabs = unref(tabs)
381
- for (let i = uTabs.length - 1; i >= 0; i--) {
382
- if (uTabs[i].closable) {
383
- for (const item of uTabs[i].pages.list()) {
384
- // removeComponent(item.id)
385
- markDeletableCache(item.id)
386
- deletableTab.add(uTabs[i].id)
387
- }
388
- unref(tabs)[i].pages.clear()
389
-
390
- unref(tabs).splice(i, 1)
391
- }
392
- }
393
- for (const stay of uTabs) {
394
- if (stay.active) {
395
- removeDeletableCache()
396
- deletableTab.clear()
397
- return
398
- }
399
- }
400
- // 如果都是非Active状态,就把最后一个active
401
- emitter.emit(MittType.TAB_ACTIVE, { id: uTabs[uTabs.length - 1].id })
402
- // active(uTabs[uTabs.length - 1].id)
403
- }
404
- const removeOtherTabs = (id: string) => {
405
- const uTabs = unref(tabs)
406
- let activeTab
407
- for (let i = uTabs.length - 1; i >= 0; i--) {
408
- if (uTabs[i].id === id) {
409
- activeTab = uTabs[i]
410
- } else if (uTabs[i].closable && uTabs[i].id !== id) {
411
- for (const item of uTabs[i].pages.list()) {
412
- // removeComponent(item.id)
413
- markDeletableCache(item.id)
414
- deletableTab.add(uTabs[i].id)
415
- }
416
- unref(tabs)[i].pages.clear()
417
- unref(tabs).splice(i, 1)
418
- }
419
- }
420
- if (!activeTab!.active) {
421
- emitter.emit(MittType.TAB_ACTIVE, { id })
422
- // active(id)
423
- } else {
424
- removeDeletableCache()
425
- deletableTab.clear()
426
- }
427
- }
428
- /**
429
- * 关闭左边
430
- * @param id
431
- */
432
- const removeLeftTabs = (id: string) => {
433
- let startIndex = -1
434
- const uTabs = unref(tabs)
435
- for (let i = 0; i < uTabs.length; i++) {
436
- if (uTabs[i].id === id) {
437
- startIndex = i - 1
438
- break
439
- }
440
- }
441
- for (let i = startIndex; i >= 0; i--) {
442
- if (uTabs[i].closable) {
443
- for (const item of uTabs[i].pages.list()) {
444
- // removeComponent(item.id)
445
- markDeletableCache(item.id)
446
- deletableTab.add(uTabs[i].id)
447
- }
448
- unref(tabs)[i].pages.clear()
449
- unref(tabs).splice(i, 1)
450
- }
451
- }
452
- for (const stay of uTabs) {
453
- if (stay.active) {
454
- removeDeletableCache()
455
- deletableTab.clear()
456
- return
457
- }
458
- }
459
- // 如果都是非Active状态,就把最后一个active
460
- emitter.emit(MittType.TAB_ACTIVE, { id: uTabs[0].id })
461
- // active(uTabs[0].id)
462
- }
463
-
464
- /**
465
- * 关闭右边
466
- * @param id
467
- */
468
- const removeRightTabs = (id: string) => {
469
- const uTabs = unref(tabs)
470
- let startIndex = uTabs.length
471
- for (let i = 0; i < uTabs.length; i++) {
472
- if (uTabs[i].id === id) {
473
- startIndex = i + 1
474
- break
475
- }
476
- }
477
- for (let i = uTabs.length - 1; i >= startIndex; i--) {
478
- if (uTabs[i].closable) {
479
- for (const item of uTabs[i].pages.list()) {
480
- // removeComponent(item.id)
481
- markDeletableCache(item.id)
482
- deletableTab.add(uTabs[i].id)
483
- }
484
- unref(tabs)[i].pages.clear()
485
- unref(tabs).splice(i, 1)
486
- }
487
- }
488
- for (const stay of uTabs) {
489
- if (stay.active) {
490
- removeDeletableCache()
491
- deletableTab.clear()
492
- return
493
- }
494
- }
495
- emitter.emit(MittType.TAB_ACTIVE, { id: uTabs[uTabs.length - 1].id })
496
- // active(uTabs[uTabs.length - 1].id)
497
- }
498
-
499
- /**
500
- * 刷新
501
- */
502
- const refreshTab = (id: string) => {
503
- // const uTabs = unref(tabs)
504
- for (const uTabs of unref(tabs)) {
505
- if (uTabs.id === id) {
506
- const currentPageId = uTabs.pages.peek()?.id
507
- for (let i = caches.value.length - 1; i >= 0; i--) {
508
- const cacheId = caches.value[i]
509
- if (cacheId === currentPageId) {
510
- caches.value.splice(i, 1)
511
- // 如果要刷新的是显示的TAB
512
- if (uTabs.active) {
513
- pageShown.value = false
514
- nextTick(() => {
515
- pageShown.value = true
516
- })
517
- }
518
- break
519
- }
520
- }
521
- break
522
- }
523
- }
524
- }
525
- /**
526
- * 全部刷新
527
- */
528
- const refreshAllTabs = () => {
529
- const refreshPage = new Set<string>()
530
- tabs.value.forEach((value) => {
531
- refreshPage.add(value.pages.peek()!.id)
532
- })
533
- for (let i = caches.value.length - 1; i >= 0; i--) {
534
- const cacheId = caches.value[i]
535
- if (refreshPage.has(cacheId)) {
536
- caches.value.splice(i, 1)
537
- }
538
- }
539
- nextTick(() => {
540
- pageShown.value = false
541
- nextTick(() => {
542
- setTimeout(() => {
543
- pageShown.value = true
544
- }, 300)
545
- })
546
- })
547
- }
548
-
549
- const addComponent = (id: string, comp: DefineComponent) => {
550
- components.set(id, comp)
551
- }
552
- const getComponent = (id: string) => {
553
- return components.get(id)
554
- }
555
- const removeComponent = (id: string) => {
556
- components.delete(id)
557
- }
558
-
559
- /**
560
- * Delete the cache after new Page loaded.
561
- * @param cacheName
562
- */
563
- const markDeletableCache = (cacheName: string) => {
564
- deletableCache.add(cacheName)
565
- }
566
- const removeDeletableCache = () => {
567
- if(deletableCache.size>0){
568
- for (let i = caches.value.length - 1; i >= 0; i--) {
569
- if (deletableCache.has(caches.value[i])) {
570
- unref(caches).splice(i, 1)
571
-
572
- }
573
- }
574
- for(const cacheName of deletableCache) {
575
- removeComponent(cacheName)
576
- }
577
- deletableCache.clear()
578
- }
579
-
580
- }
581
- const removeCache = (cacheName: string) => {
582
- for (let i = caches.value.length - 1; i >= 0; i--) {
583
- if (cacheName === caches.value[i]) {
584
- unref(caches).splice(i, 1)
585
- }
586
- }
587
- }
588
- const addCache = (cacheName: string) => {
589
- const cacheSet = new Set(caches.value)
590
- if (!cacheSet.has(cacheName)) {
591
- caches.value.push(cacheName)
592
- }
593
- }
594
-
595
- /**
596
- * active the tab,
597
- * @param id
598
- * @param route
599
- * @return true if already actived
600
- */
601
- const active = (id: string, route = true) => {
602
- // return new Promise((resolve)=>{
603
- emitter.emit('FORWARD')
604
- for (let i = tabs.value.length - 1; i >= 0; i--) {
605
- const tab = tabs.value[i] as ITabItem
606
- if (tab.id === id) {
607
- if (tab.active) {
608
- break
609
- } else {
610
- tab.active = true
611
- // pageShown.value = false
612
- updateSession(tab)
613
- if (route) {
614
- const top = tab.pages.peek()
615
- router.push({
616
- path: top!.path,
617
- query: top!.query
618
- })
619
- }
620
- }
621
- } else {
622
- tabs.value[i].active = false
623
- }
624
- }
625
- // resolve(true)
626
- // })
627
- }
628
- /**
629
- * save current tab info into Browser's session
630
- * @param id
631
- */
632
- const updateSession = (tab: ITabItem) => {
633
- // window.sessionStorage.setItem('tabItems', JSON.stringify(currentItems?.values()))
634
- window.sessionStorage.setItem(sessionPrefix+SESSION_TAB_NAME, JSON.stringify(tab))
635
- }
636
- const clearSession = () => {
637
- // window.sessionStorage.setItem('tabItems', JSON.stringify(currentItems?.values()))
638
- window.sessionStorage.removeItem(sessionPrefix+SESSION_TAB_NAME)
639
- }
640
- const reset = () => {
641
- removeAllTabs()
642
- // pageShown.value = false
643
- // destroy()
644
- // nextTick(() => {
645
- // // unref(tabs).push(...defaultTabs)
646
- // // emitter.emit(MittType.TAB_ACTIVE, { id: defaultTabs[0].id! })
647
- // // // pageShown.value = false
648
- // nextTick(() => {
649
- // pageShown.value = true
650
- // })
651
- // })
652
- // active(defaultTabs[0].id)
653
- }
654
- const destroy = () => {
655
- unref(tabs).splice(0)
656
- deletableCache.clear()
657
- deletableTab.clear()
658
- unref(caches).splice(0)
659
- components.clear()
660
- clearSession()
661
- }
662
- const setMaxSize = (size: number) => {
663
- max = size
664
- }
665
- const setGlobalScroll = (globalScroll: boolean) => {
666
- scrollbar = globalScroll
667
- }
668
-
669
- const setSessionPrefix = (prefix: string) => {
670
- sessionPrefix = prefix
671
- }
672
- return {
673
- tabs,
674
- caches,
675
- pageShown,
676
- initialed,
677
- setMaxSize,
678
- canAddTab,
679
- initial,
680
- size,
681
- active,
682
- destroy,
683
- reset,
684
- addCache,
685
- removeCache,
686
- getTab,
687
- addTab,
688
- removeTab,
689
- removeAllTabs,
690
- removeLeftTabs,
691
- removeRightTabs,
692
- removeOtherTabs,
693
- hasTab,
694
- renewTab,
695
- addPage,
696
- addComponent,
697
- getComponent,
698
- removeComponent,
699
- markDeletableCache,
700
- removeDeletableCache,
701
- refreshTab,
702
- refreshAllTabs,
703
- addPageScroller,
704
- setGlobalScroll,
705
- clearSession,
706
- setSessionPrefix
707
- }
708
- }