mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 01:47:47 +08:00
44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
import { log } from '@/utils/logger'
|
|
import type { Router } from 'vue-router'
|
|
|
|
const PREFETCH_COOLDOWN_MS = 5 * 1000
|
|
|
|
const lastPrefetchAt = new Map<string, number>()
|
|
|
|
type PrefetchableRouteLoader = (() => unknown) & {
|
|
prefetch?: () => Promise<unknown>
|
|
}
|
|
|
|
/**
|
|
* 预取目标路由链中的异步组件。
|
|
*
|
|
* 直接从 Router 解析组件,避免维护一份容易遗漏用户页和新增管理页的硬编码表。
|
|
*/
|
|
export function prefetchNavigationTarget(router: Router, href: string): void {
|
|
const now = Date.now()
|
|
const lastRun = lastPrefetchAt.get(href) ?? 0
|
|
if (now - lastRun < PREFETCH_COOLDOWN_MS) {
|
|
return
|
|
}
|
|
|
|
const loaders = router.resolve(href).matched.flatMap((record) =>
|
|
Object.values(record.components ?? {})
|
|
.filter((component): component is PrefetchableRouteLoader =>
|
|
typeof component === 'function'
|
|
&& typeof (component as PrefetchableRouteLoader).prefetch === 'function'
|
|
)
|
|
.map(component => component.prefetch as () => Promise<unknown>)
|
|
)
|
|
if (loaders.length === 0) return
|
|
|
|
lastPrefetchAt.set(href, now)
|
|
|
|
for (const loader of new Set(loaders)) {
|
|
void Promise.resolve()
|
|
.then(() => loader())
|
|
.catch((err) => {
|
|
log.debug('[navigationPrefetch] ignore prefetch failure', err)
|
|
})
|
|
}
|
|
}
|