vue-stack-tabs 1.4.1 → 1.4.2
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.
- package/dist/hooks/tabPanel/pageComponentFactory.d.ts +5 -2
- package/dist/hooks/tabPanel/refresh.d.ts +6 -3
- package/dist/hooks/tabPanel/tabStore.d.ts +69 -0
- package/dist/hooks/useTabPanel.d.ts +13 -3
- package/dist/vue-stack-tabs.es.js +1 -1
- package/package.json +1 -1
- package/src/lib/hooks/tabPanel/pageComponentFactory.tsx +13 -19
- package/src/lib/hooks/tabPanel/refresh.ts +20 -16
- package/src/lib/hooks/tabPanel/tabStore.ts +595 -0
- package/src/lib/hooks/useTabActions.ts +2 -2
- package/src/lib/hooks/useTabPanel.tsx +123 -170
- package/src/lib/hooks/useTabRouter.ts +32 -37
|
@@ -2,7 +2,6 @@ import { defu } from 'defu'
|
|
|
2
2
|
import { getCurrentInstance } from 'vue'
|
|
3
3
|
import type { ComponentInternalInstance } from 'vue'
|
|
4
4
|
import type { LocationQueryRaw, RouteLocationPathRaw } from 'vue-router'
|
|
5
|
-
import type { ITabPage } from '../model/TabModel'
|
|
6
5
|
import { isNavigationFailure, useRoute, useRouter } from 'vue-router'
|
|
7
6
|
|
|
8
7
|
import useTabPanel from './useTabPanel'
|
|
@@ -18,18 +17,6 @@ import { runNavigationTransaction } from './tabPanel/navigationTransaction'
|
|
|
18
17
|
|
|
19
18
|
import { createPageId } from '../utils/tabInfoEncoder'
|
|
20
19
|
|
|
21
|
-
interface PageStackLike {
|
|
22
|
-
clear: () => void
|
|
23
|
-
push: (page: ITabPage) => void
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const restorePages = (stack: PageStackLike, pages: ITabPage[]) => {
|
|
27
|
-
stack.clear()
|
|
28
|
-
for (const page of pages) {
|
|
29
|
-
stack.push(clonePage(page))
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
20
|
/**
|
|
34
21
|
* useTabRouter - 标签内路由 Hook
|
|
35
22
|
*
|
|
@@ -62,7 +49,19 @@ export default function useTabRouter() {
|
|
|
62
49
|
const route = useRoute()
|
|
63
50
|
const router = useRouter()
|
|
64
51
|
const emitter = useTabEmitter()
|
|
65
|
-
const {
|
|
52
|
+
const {
|
|
53
|
+
getTab,
|
|
54
|
+
getTopPage,
|
|
55
|
+
getPages,
|
|
56
|
+
appendPage,
|
|
57
|
+
popPages,
|
|
58
|
+
getPageSnapshot,
|
|
59
|
+
replacePages,
|
|
60
|
+
updatePage,
|
|
61
|
+
evictPageCache,
|
|
62
|
+
addPageScroller,
|
|
63
|
+
active: activateTab
|
|
64
|
+
} = useTabPanel()
|
|
66
65
|
|
|
67
66
|
/**
|
|
68
67
|
* 当前标签的编码信息字符串,存于 URL query.__tab。
|
|
@@ -87,7 +86,7 @@ export default function useTabRouter() {
|
|
|
87
86
|
const targetQuery = (to.query || {}) as LocationQueryRaw
|
|
88
87
|
|
|
89
88
|
if (tab) {
|
|
90
|
-
const top = tab.
|
|
89
|
+
const top = getTopPage(tab.id)
|
|
91
90
|
if (top && top.path === to.path) {
|
|
92
91
|
if (isSameQueryIgnoringReserved(targetQuery, top.query || {})) {
|
|
93
92
|
if (!tab.active) {
|
|
@@ -107,10 +106,10 @@ export default function useTabRouter() {
|
|
|
107
106
|
let optimisticPageId = ''
|
|
108
107
|
runNavigationTransaction({
|
|
109
108
|
apply: () => {
|
|
110
|
-
const snapshot = tab ? tab.
|
|
109
|
+
const snapshot = tab ? getPageSnapshot(tab.id) : []
|
|
111
110
|
if (tab) {
|
|
112
111
|
optimisticPageId = createPageId()
|
|
113
|
-
tab.
|
|
112
|
+
appendPage(tab.id, {
|
|
114
113
|
id: optimisticPageId,
|
|
115
114
|
tabId: tab.id,
|
|
116
115
|
path: to.path,
|
|
@@ -121,14 +120,14 @@ export default function useTabRouter() {
|
|
|
121
120
|
},
|
|
122
121
|
navigate: () => router.push({ path: to.path, query }),
|
|
123
122
|
rollback: (snapshot) => {
|
|
124
|
-
if (tab)
|
|
123
|
+
if (tab) replacePages(tab.id, snapshot)
|
|
125
124
|
},
|
|
126
125
|
isFailureResult: isNavigationFailure,
|
|
127
126
|
isCurrent: () => navigationVersion === transactionVersion,
|
|
128
127
|
cleanupStale: () => {
|
|
129
128
|
if (!tab || !optimisticPageId) return
|
|
130
|
-
const pages = tab.
|
|
131
|
-
|
|
129
|
+
const pages = getPages(tab.id).filter((page) => page.id !== optimisticPageId)
|
|
130
|
+
replacePages(tab.id, pages)
|
|
132
131
|
}
|
|
133
132
|
}).catch((error: unknown) => {
|
|
134
133
|
if (!import.meta.env.PROD) {
|
|
@@ -149,7 +148,7 @@ export default function useTabRouter() {
|
|
|
149
148
|
const tab = getTab(tabId)
|
|
150
149
|
if (!tab) return false
|
|
151
150
|
|
|
152
|
-
const
|
|
151
|
+
const pages = getPages(tab.id)
|
|
153
152
|
let steps = 0
|
|
154
153
|
|
|
155
154
|
if (typeof to === 'number') {
|
|
@@ -157,10 +156,9 @@ export default function useTabRouter() {
|
|
|
157
156
|
} else {
|
|
158
157
|
const parsed = parseUrl(to)
|
|
159
158
|
const targetQuery = parsed.query || {}
|
|
160
|
-
const pages = stack.readonlyList()
|
|
161
159
|
let found = false
|
|
162
160
|
|
|
163
|
-
for (let i =
|
|
161
|
+
for (let i = pages.length - 2; i >= 0; i--) {
|
|
164
162
|
steps++
|
|
165
163
|
const page = pages[i]
|
|
166
164
|
if (
|
|
@@ -184,33 +182,30 @@ export default function useTabRouter() {
|
|
|
184
182
|
|
|
185
183
|
if (steps <= 0) return false
|
|
186
184
|
|
|
187
|
-
|
|
185
|
+
const availableSteps = pages.length - 1
|
|
186
|
+
if (availableSteps < steps) {
|
|
188
187
|
// 请求退栈步数大于当前可用层数时,仅退到栈底(首页);开发模式下提示维护者。
|
|
189
188
|
if (!import.meta.env.PROD) {
|
|
190
189
|
console.warn(
|
|
191
|
-
`[vue-stack-tabs] backward requested ${steps} steps but stack only has ${
|
|
190
|
+
`[vue-stack-tabs] backward requested ${steps} steps but stack only has ${availableSteps} available.`
|
|
192
191
|
)
|
|
193
192
|
}
|
|
194
|
-
steps =
|
|
193
|
+
steps = availableSteps
|
|
195
194
|
}
|
|
196
195
|
|
|
197
196
|
if (steps <= 0) return false
|
|
198
197
|
|
|
199
|
-
const originalPages =
|
|
200
|
-
const recyclingBin
|
|
201
|
-
for (let i = 0; i < steps; i++) {
|
|
202
|
-
const popped = stack.pop()
|
|
203
|
-
if (popped) recyclingBin.push(popped.id)
|
|
204
|
-
}
|
|
198
|
+
const originalPages = getPageSnapshot(tab.id)
|
|
199
|
+
const recyclingBin = popPages(tab.id, steps).map((page) => page.id)
|
|
205
200
|
|
|
206
|
-
const target =
|
|
201
|
+
const target = getTopPage(tab.id)
|
|
207
202
|
if (!target) {
|
|
208
|
-
|
|
203
|
+
replacePages(tab.id, originalPages)
|
|
209
204
|
return false
|
|
210
205
|
}
|
|
211
206
|
|
|
212
207
|
if (backQuery) {
|
|
213
|
-
target._backParams
|
|
208
|
+
updatePage(tab.id, target.id, { _backParams: backQuery })
|
|
214
209
|
}
|
|
215
210
|
|
|
216
211
|
emitter.emit(TabEventType.BACKWARD)
|
|
@@ -222,7 +217,7 @@ export default function useTabRouter() {
|
|
|
222
217
|
runNavigationTransaction({
|
|
223
218
|
apply: () => originalPages,
|
|
224
219
|
navigate: () => router.push({ path: target.path, query: targetQueryWithTab }),
|
|
225
|
-
rollback: (snapshot) =>
|
|
220
|
+
rollback: (snapshot) => replacePages(tab.id, snapshot),
|
|
226
221
|
isFailureResult: isNavigationFailure,
|
|
227
222
|
isCurrent: () => navigationVersion === transactionVersion,
|
|
228
223
|
commit: () => {
|
|
@@ -231,7 +226,7 @@ export default function useTabRouter() {
|
|
|
231
226
|
}
|
|
232
227
|
},
|
|
233
228
|
cleanupStale: () => {
|
|
234
|
-
const activePageIds = new Set(
|
|
229
|
+
const activePageIds = new Set(getPages(tab.id).map((page) => page.id))
|
|
235
230
|
for (const id of recyclingBin) {
|
|
236
231
|
if (!activePageIds.has(id)) evictPageCache(id)
|
|
237
232
|
}
|