@tanstack/vue-router 1.141.4 → 1.141.6
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/esm/ClientOnly.js +33 -0
- package/dist/esm/ClientOnly.js.map +1 -0
- package/dist/esm/Match.js +66 -39
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Transitioner.js +14 -5
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lazyRouteComponent.d.ts +0 -6
- package/dist/esm/lazyRouteComponent.js +5 -24
- package/dist/esm/lazyRouteComponent.js.map +1 -1
- package/dist/esm/link.d.ts +4 -0
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/route.d.ts +6 -1
- package/dist/esm/route.js +25 -0
- package/dist/esm/route.js.map +1 -1
- package/dist/source/Match.jsx +90 -63
- package/dist/source/Match.jsx.map +1 -1
- package/dist/source/Transitioner.jsx +12 -5
- package/dist/source/Transitioner.jsx.map +1 -1
- package/dist/source/index.d.ts +2 -1
- package/dist/source/index.jsx +1 -0
- package/dist/source/index.jsx.map +1 -1
- package/dist/source/lazyRouteComponent.d.ts +0 -6
- package/dist/source/lazyRouteComponent.jsx +3 -23
- package/dist/source/lazyRouteComponent.jsx.map +1 -1
- package/dist/source/link.d.ts +4 -0
- package/dist/source/link.jsx.map +1 -1
- package/dist/source/route.d.ts +6 -1
- package/dist/source/route.js +13 -0
- package/dist/source/route.js.map +1 -1
- package/package.json +2 -2
- package/src/Match.tsx +115 -73
- package/src/Transitioner.tsx +15 -6
- package/src/index.tsx +2 -0
- package/src/lazyRouteComponent.tsx +10 -32
- package/src/link.tsx +20 -0
- package/src/route.ts +33 -1
package/src/Match.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
rootRouteId,
|
|
10
10
|
} from '@tanstack/router-core'
|
|
11
11
|
import { CatchBoundary, ErrorComponent } from './CatchBoundary'
|
|
12
|
+
import { ClientOnly } from './ClientOnly'
|
|
12
13
|
import { useRouterState } from './useRouterState'
|
|
13
14
|
import { useRouter } from './useRouter'
|
|
14
15
|
import { CatchNotFound } from './not-found'
|
|
@@ -16,7 +17,7 @@ import { matchContext } from './matchContext'
|
|
|
16
17
|
import { renderRouteNotFound } from './renderRouteNotFound'
|
|
17
18
|
import { ScrollRestoration } from './scroll-restoration'
|
|
18
19
|
import type { VNode } from 'vue'
|
|
19
|
-
import type { AnyRoute } from '@tanstack/router-core'
|
|
20
|
+
import type { AnyRoute, RootRouteOptions } from '@tanstack/router-core'
|
|
20
21
|
|
|
21
22
|
export const Match = Vue.defineComponent({
|
|
22
23
|
name: 'Match',
|
|
@@ -67,6 +68,8 @@ export const Match = Vue.defineComponent({
|
|
|
67
68
|
routeId,
|
|
68
69
|
parentRouteId,
|
|
69
70
|
loadedAt: s.loadedAt,
|
|
71
|
+
ssr: match.ssr,
|
|
72
|
+
_displayPending: match._displayPending,
|
|
70
73
|
}
|
|
71
74
|
},
|
|
72
75
|
})
|
|
@@ -86,6 +89,10 @@ export const Match = Vue.defineComponent({
|
|
|
86
89
|
router?.options?.defaultPendingComponent,
|
|
87
90
|
)
|
|
88
91
|
|
|
92
|
+
const pendingElement = Vue.computed(() =>
|
|
93
|
+
PendingComponent.value ? Vue.h(PendingComponent.value) : undefined,
|
|
94
|
+
)
|
|
95
|
+
|
|
89
96
|
const routeErrorComponent = Vue.computed(
|
|
90
97
|
() =>
|
|
91
98
|
route.value?.options?.errorComponent ??
|
|
@@ -104,6 +111,17 @@ export const Match = Vue.defineComponent({
|
|
|
104
111
|
: route.value?.options?.notFoundComponent,
|
|
105
112
|
)
|
|
106
113
|
|
|
114
|
+
const hasShellComponent = Vue.computed(() => {
|
|
115
|
+
if (!route.value?.isRoot) return false
|
|
116
|
+
return !!(route.value.options as RootRouteOptions).shellComponent
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const ShellComponent = Vue.computed(() =>
|
|
120
|
+
hasShellComponent.value
|
|
121
|
+
? ((route.value!.options as RootRouteOptions).shellComponent as any)
|
|
122
|
+
: null,
|
|
123
|
+
)
|
|
124
|
+
|
|
107
125
|
// Create a ref for the current matchId that we provide to child components
|
|
108
126
|
// This ref is updated to the ACTUAL matchId found (which may differ from props during transitions)
|
|
109
127
|
const matchIdRef = Vue.ref(matchData.value?.matchId ?? props.matchId)
|
|
@@ -127,82 +145,89 @@ export const Match = Vue.defineComponent({
|
|
|
127
145
|
// Use the actual matchId from matchData, not props (which may be stale)
|
|
128
146
|
const actualMatchId = matchData.value?.matchId ?? props.matchId
|
|
129
147
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
148
|
+
const resolvedNoSsr =
|
|
149
|
+
matchData.value?.ssr === false || matchData.value?.ssr === 'data-only'
|
|
150
|
+
const shouldClientOnly =
|
|
151
|
+
resolvedNoSsr || !!matchData.value?._displayPending
|
|
152
|
+
|
|
153
|
+
const renderMatchContent = (): VNode => {
|
|
154
|
+
const matchInner = Vue.h(MatchInner, { matchId: actualMatchId })
|
|
155
|
+
|
|
156
|
+
let content: VNode = shouldClientOnly
|
|
157
|
+
? Vue.h(
|
|
158
|
+
ClientOnly,
|
|
159
|
+
{
|
|
160
|
+
fallback: pendingElement.value,
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
default: () => matchInner,
|
|
164
|
+
},
|
|
143
165
|
)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
: matchInner
|
|
167
|
+
|
|
168
|
+
// Wrap in NotFound boundary if needed
|
|
169
|
+
if (routeNotFoundComponent.value) {
|
|
170
|
+
content = Vue.h(CatchNotFound, {
|
|
171
|
+
fallback: (error: any) => {
|
|
172
|
+
// If the current not found handler doesn't exist or it has a
|
|
173
|
+
// route ID which doesn't match the current route, rethrow the error
|
|
174
|
+
if (
|
|
175
|
+
!routeNotFoundComponent.value ||
|
|
176
|
+
(error.routeId && error.routeId !== matchData.value?.routeId) ||
|
|
177
|
+
(!error.routeId && route.value && !route.value.isRoot)
|
|
178
|
+
)
|
|
179
|
+
throw error
|
|
180
|
+
|
|
181
|
+
return Vue.h(routeNotFoundComponent.value, error)
|
|
182
|
+
},
|
|
183
|
+
children: content,
|
|
184
|
+
})
|
|
185
|
+
}
|
|
151
186
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
187
|
+
// Wrap in error boundary if needed
|
|
188
|
+
if (routeErrorComponent.value) {
|
|
189
|
+
content = CatchBoundary({
|
|
190
|
+
getResetKey: () => matchData.value?.loadedAt ?? 0,
|
|
191
|
+
errorComponent: routeErrorComponent.value || ErrorComponent,
|
|
192
|
+
onCatch: (error: Error) => {
|
|
193
|
+
// Forward not found errors (we don't want to show the error component for these)
|
|
194
|
+
if (isNotFound(error)) throw error
|
|
195
|
+
warning(false, `Error in route match: ${actualMatchId}`)
|
|
196
|
+
routeOnCatch.value?.(error)
|
|
197
|
+
},
|
|
198
|
+
children: content,
|
|
199
|
+
})
|
|
200
|
+
}
|
|
166
201
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
202
|
+
// Add scroll restoration if needed
|
|
203
|
+
const withScrollRestoration: Array<VNode> = [
|
|
204
|
+
content,
|
|
205
|
+
matchData.value?.parentRouteId === rootRouteId &&
|
|
206
|
+
router.options.scrollRestoration
|
|
207
|
+
? Vue.h(Vue.Fragment, null, [
|
|
208
|
+
Vue.h(OnRendered),
|
|
209
|
+
Vue.h(ScrollRestoration),
|
|
210
|
+
])
|
|
211
|
+
: null,
|
|
212
|
+
].filter(Boolean) as Array<VNode>
|
|
213
|
+
|
|
214
|
+
// Return single child directly to avoid Fragment wrapper that causes hydration mismatch
|
|
215
|
+
if (withScrollRestoration.length === 1) {
|
|
216
|
+
return withScrollRestoration[0]!
|
|
217
|
+
}
|
|
174
218
|
|
|
175
|
-
|
|
176
|
-
content = Vue.h(
|
|
177
|
-
Vue.Suspense,
|
|
178
|
-
{
|
|
179
|
-
fallback: PendingComponent.value
|
|
180
|
-
? Vue.h(PendingComponent.value)
|
|
181
|
-
: null,
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
default: () => content,
|
|
185
|
-
},
|
|
186
|
-
)
|
|
219
|
+
return Vue.h(Vue.Fragment, null, withScrollRestoration)
|
|
187
220
|
}
|
|
188
221
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
content,
|
|
192
|
-
matchData.value?.parentRouteId === rootRouteId &&
|
|
193
|
-
router.options.scrollRestoration
|
|
194
|
-
? Vue.h(Vue.Fragment, null, [
|
|
195
|
-
Vue.h(OnRendered),
|
|
196
|
-
Vue.h(ScrollRestoration),
|
|
197
|
-
])
|
|
198
|
-
: null,
|
|
199
|
-
].filter(Boolean) as Array<VNode>
|
|
200
|
-
|
|
201
|
-
// Return single child directly to avoid Fragment wrapper that causes hydration mismatch
|
|
202
|
-
if (withScrollRestoration.length === 1) {
|
|
203
|
-
return withScrollRestoration[0]!
|
|
222
|
+
if (!hasShellComponent.value) {
|
|
223
|
+
return renderMatchContent()
|
|
204
224
|
}
|
|
205
|
-
|
|
225
|
+
|
|
226
|
+
return Vue.h(ShellComponent.value, null, {
|
|
227
|
+
// Important: return a fresh VNode on each slot invocation so that shell
|
|
228
|
+
// components can re-render without reusing a cached VNode instance.
|
|
229
|
+
default: () => renderMatchContent(),
|
|
230
|
+
})
|
|
206
231
|
}
|
|
207
232
|
},
|
|
208
233
|
})
|
|
@@ -304,6 +329,9 @@ export const MatchInner = Vue.defineComponent({
|
|
|
304
329
|
id: match.id,
|
|
305
330
|
status: match.status,
|
|
306
331
|
error: match.error,
|
|
332
|
+
ssr: match.ssr,
|
|
333
|
+
_forcePending: match._forcePending,
|
|
334
|
+
_displayPending: match._displayPending,
|
|
307
335
|
},
|
|
308
336
|
remountKey,
|
|
309
337
|
}
|
|
@@ -320,11 +348,25 @@ export const MatchInner = Vue.defineComponent({
|
|
|
320
348
|
|
|
321
349
|
return (): VNode | null => {
|
|
322
350
|
// If match doesn't exist, return null (component is being unmounted or not ready)
|
|
323
|
-
if (!combinedState.value || !match.value || !route.value)
|
|
324
|
-
return null
|
|
325
|
-
}
|
|
351
|
+
if (!combinedState.value || !match.value || !route.value) return null
|
|
326
352
|
|
|
327
353
|
// Handle different match statuses
|
|
354
|
+
if (match.value._displayPending) {
|
|
355
|
+
const PendingComponent =
|
|
356
|
+
route.value.options.pendingComponent ??
|
|
357
|
+
router.options.defaultPendingComponent
|
|
358
|
+
|
|
359
|
+
return PendingComponent ? Vue.h(PendingComponent) : null
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (match.value._forcePending) {
|
|
363
|
+
const PendingComponent =
|
|
364
|
+
route.value.options.pendingComponent ??
|
|
365
|
+
router.options.defaultPendingComponent
|
|
366
|
+
|
|
367
|
+
return PendingComponent ? Vue.h(PendingComponent) : null
|
|
368
|
+
}
|
|
369
|
+
|
|
328
370
|
if (match.value.status === 'notFound') {
|
|
329
371
|
invariant(isNotFound(match.value.error), 'Expected a notFound error')
|
|
330
372
|
return renderRouteNotFound(router, route.value, match.value.error)
|
package/src/Transitioner.tsx
CHANGED
|
@@ -136,6 +136,13 @@ export function useTransitionerSetup() {
|
|
|
136
136
|
|
|
137
137
|
Vue.onMounted(() => {
|
|
138
138
|
isMounted.value = true
|
|
139
|
+
if (!isAnyPending.value) {
|
|
140
|
+
router.__store.setState((s) =>
|
|
141
|
+
s.status === 'pending'
|
|
142
|
+
? { ...s, status: 'idle', resolvedLocation: s.location }
|
|
143
|
+
: s,
|
|
144
|
+
)
|
|
145
|
+
}
|
|
139
146
|
})
|
|
140
147
|
|
|
141
148
|
Vue.onUnmounted(() => {
|
|
@@ -201,6 +208,14 @@ export function useTransitionerSetup() {
|
|
|
201
208
|
Vue.watch(isAnyPending, (newValue) => {
|
|
202
209
|
if (!isMounted.value) return
|
|
203
210
|
try {
|
|
211
|
+
if (!newValue && router.__store.state.status === 'pending') {
|
|
212
|
+
router.__store.setState((s) => ({
|
|
213
|
+
...s,
|
|
214
|
+
status: 'idle',
|
|
215
|
+
resolvedLocation: s.location,
|
|
216
|
+
}))
|
|
217
|
+
}
|
|
218
|
+
|
|
204
219
|
// The router was pending and now it's not
|
|
205
220
|
if (previousIsAnyPending.value.previous && !newValue) {
|
|
206
221
|
const changeInfo = getLocationChangeInfo(router.state)
|
|
@@ -209,12 +224,6 @@ export function useTransitionerSetup() {
|
|
|
209
224
|
...changeInfo,
|
|
210
225
|
})
|
|
211
226
|
|
|
212
|
-
router.__store.setState((s) => ({
|
|
213
|
-
...s,
|
|
214
|
-
status: 'idle',
|
|
215
|
-
resolvedLocation: s.location,
|
|
216
|
-
}))
|
|
217
|
-
|
|
218
227
|
if (changeInfo.hrefChanged) {
|
|
219
228
|
handleHashScroll(router)
|
|
220
229
|
}
|
package/src/index.tsx
CHANGED
|
@@ -219,6 +219,7 @@ export type {
|
|
|
219
219
|
ActiveLinkOptions,
|
|
220
220
|
LinkProps,
|
|
221
221
|
LinkComponent,
|
|
222
|
+
LinkComponentRoute,
|
|
222
223
|
LinkComponentProps,
|
|
223
224
|
CreateLinkProps,
|
|
224
225
|
} from './link'
|
|
@@ -346,3 +347,4 @@ export type {
|
|
|
346
347
|
LocationRewrite,
|
|
347
348
|
LocationRewriteFunction,
|
|
348
349
|
} from '@tanstack/router-core'
|
|
350
|
+
export { ClientOnly } from './ClientOnly'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Vue from 'vue'
|
|
2
2
|
import { Outlet } from './Match'
|
|
3
|
+
import { ClientOnly } from './ClientOnly'
|
|
3
4
|
import type { AsyncRouteComponent } from './route'
|
|
4
5
|
|
|
5
6
|
// If the load fails due to module not found, it may mean a new version of
|
|
@@ -19,34 +20,6 @@ function isModuleNotFoundError(error: any): boolean {
|
|
|
19
20
|
)
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
export function ClientOnly(props: { children?: any; fallback?: Vue.VNode }) {
|
|
23
|
-
const hydrated = useHydrated()
|
|
24
|
-
|
|
25
|
-
return () => {
|
|
26
|
-
if (hydrated.value) {
|
|
27
|
-
return props.children
|
|
28
|
-
}
|
|
29
|
-
return props.fallback || null
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function useHydrated() {
|
|
34
|
-
// Only hydrate on client-side, never on server
|
|
35
|
-
const hydrated = Vue.ref(false)
|
|
36
|
-
|
|
37
|
-
// If on server, return false
|
|
38
|
-
if (typeof window === 'undefined') {
|
|
39
|
-
return Vue.computed(() => false)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// On client, set to true once mounted
|
|
43
|
-
Vue.onMounted(() => {
|
|
44
|
-
hydrated.value = true
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
return hydrated
|
|
48
|
-
}
|
|
49
|
-
|
|
50
23
|
export function lazyRouteComponent<
|
|
51
24
|
T extends Record<string, any>,
|
|
52
25
|
TKey extends keyof T = 'default',
|
|
@@ -156,10 +129,15 @@ export function lazyRouteComponent<
|
|
|
156
129
|
|
|
157
130
|
// If SSR is disabled for this component
|
|
158
131
|
if (ssr?.() === false) {
|
|
159
|
-
return Vue.h(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
132
|
+
return Vue.h(
|
|
133
|
+
ClientOnly,
|
|
134
|
+
{
|
|
135
|
+
fallback: Vue.h(Outlet),
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
default: () => Vue.h(component.value, props),
|
|
139
|
+
},
|
|
140
|
+
)
|
|
163
141
|
}
|
|
164
142
|
|
|
165
143
|
// Regular render with the loaded component
|
package/src/link.tsx
CHANGED
|
@@ -630,6 +630,26 @@ export type LinkComponent<TComp> = <
|
|
|
630
630
|
props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
|
|
631
631
|
) => Vue.VNode
|
|
632
632
|
|
|
633
|
+
export interface LinkComponentRoute<
|
|
634
|
+
in out TDefaultFrom extends string = string,
|
|
635
|
+
> {
|
|
636
|
+
defaultFrom: TDefaultFrom
|
|
637
|
+
<
|
|
638
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
639
|
+
const TTo extends string | undefined = undefined,
|
|
640
|
+
const TMaskTo extends string = '',
|
|
641
|
+
>(
|
|
642
|
+
props: LinkComponentProps<
|
|
643
|
+
'a',
|
|
644
|
+
TRouter,
|
|
645
|
+
this['defaultFrom'],
|
|
646
|
+
TTo,
|
|
647
|
+
this['defaultFrom'],
|
|
648
|
+
TMaskTo
|
|
649
|
+
>,
|
|
650
|
+
): Vue.VNode
|
|
651
|
+
}
|
|
652
|
+
|
|
633
653
|
export function createLink<const TComp>(
|
|
634
654
|
Comp: Constrain<TComp, any, (props: CreateLinkProps) => Vue.VNode>,
|
|
635
655
|
): LinkComponent<TComp> {
|
package/src/route.ts
CHANGED
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
BaseRouteApi,
|
|
5
5
|
notFound,
|
|
6
6
|
} from '@tanstack/router-core'
|
|
7
|
+
import * as Vue from 'vue'
|
|
8
|
+
import { Link } from './link'
|
|
7
9
|
import { useLoaderData } from './useLoaderData'
|
|
8
10
|
import { useLoaderDeps } from './useLoaderDeps'
|
|
9
11
|
import { useParams } from './useParams'
|
|
@@ -42,8 +44,8 @@ import type { UseMatchRoute } from './useMatch'
|
|
|
42
44
|
import type { UseLoaderDepsRoute } from './useLoaderDeps'
|
|
43
45
|
import type { UseParamsRoute } from './useParams'
|
|
44
46
|
import type { UseSearchRoute } from './useSearch'
|
|
45
|
-
import type * as Vue from 'vue'
|
|
46
47
|
import type { UseRouteContextRoute } from './useRouteContext'
|
|
48
|
+
import type { LinkComponentRoute } from './link'
|
|
47
49
|
|
|
48
50
|
// Structural type for Vue SFC components (.vue files)
|
|
49
51
|
// Uses structural matching to accept Vue components without breaking
|
|
@@ -73,6 +75,7 @@ declare module '@tanstack/router-core' {
|
|
|
73
75
|
useLoaderDeps: UseLoaderDepsRoute<TId>
|
|
74
76
|
useLoaderData: UseLoaderDataRoute<TId>
|
|
75
77
|
useNavigate: () => UseNavigateResult<TFullPath>
|
|
78
|
+
Link: LinkComponentRoute<TFullPath>
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
|
|
@@ -140,6 +143,19 @@ export class RouteApi<
|
|
|
140
143
|
notFound = (opts?: NotFoundError) => {
|
|
141
144
|
return notFound({ routeId: this.id as string, ...opts })
|
|
142
145
|
}
|
|
146
|
+
|
|
147
|
+
Link: LinkComponentRoute<RouteTypesById<TRouter, TId>['fullPath']> = ((
|
|
148
|
+
props,
|
|
149
|
+
ctx?: Vue.SetupContext,
|
|
150
|
+
) => {
|
|
151
|
+
const router = useRouter()
|
|
152
|
+
const fullPath = router.routesById[this.id as string].fullPath
|
|
153
|
+
return Vue.h(
|
|
154
|
+
Link as any,
|
|
155
|
+
{ from: fullPath as never, ...(props as any) },
|
|
156
|
+
ctx?.slots,
|
|
157
|
+
)
|
|
158
|
+
}) as LinkComponentRoute<RouteTypesById<TRouter, TId>['fullPath']>
|
|
143
159
|
}
|
|
144
160
|
|
|
145
161
|
export class Route<
|
|
@@ -277,6 +293,14 @@ export class Route<
|
|
|
277
293
|
useNavigate = (): UseNavigateResult<TFullPath> => {
|
|
278
294
|
return useNavigate({ from: this.fullPath })
|
|
279
295
|
}
|
|
296
|
+
|
|
297
|
+
Link: LinkComponentRoute<TFullPath> = ((props, ctx?: Vue.SetupContext) => {
|
|
298
|
+
return Vue.h(
|
|
299
|
+
Link as any,
|
|
300
|
+
{ from: this.fullPath as never, ...(props as any) },
|
|
301
|
+
ctx?.slots,
|
|
302
|
+
)
|
|
303
|
+
}) as LinkComponentRoute<TFullPath>
|
|
280
304
|
}
|
|
281
305
|
|
|
282
306
|
export function createRoute<
|
|
@@ -515,6 +539,14 @@ export class RootRoute<
|
|
|
515
539
|
useNavigate = (): UseNavigateResult<'/'> => {
|
|
516
540
|
return useNavigate({ from: this.fullPath })
|
|
517
541
|
}
|
|
542
|
+
|
|
543
|
+
Link: LinkComponentRoute<'/'> = ((props, ctx?: Vue.SetupContext) => {
|
|
544
|
+
return Vue.h(
|
|
545
|
+
Link as any,
|
|
546
|
+
{ from: this.fullPath as never, ...(props as any) },
|
|
547
|
+
ctx?.slots,
|
|
548
|
+
)
|
|
549
|
+
}) as LinkComponentRoute<'/'>
|
|
518
550
|
}
|
|
519
551
|
|
|
520
552
|
export function createRouteMask<
|