mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-22 21:06:32 +00:00
82 lines
2.9 KiB
TypeScript
82 lines
2.9 KiB
TypeScript
/**
|
|
* 主题运行时页面级增强(与主题骨架解耦,index.ts 只保留声明式结构):
|
|
* - guide 页面启用 medium-zoom 图片缩放(首页用不上,避免 ~60KB 浪费)
|
|
* - 移除 VitePress 默认注入的 Inter Web 字体 preload(我们用 system-ui 优先)
|
|
*/
|
|
import { onMounted, onUnmounted, watch, nextTick } from 'vue'
|
|
import { useRoute } from 'vitepress'
|
|
|
|
/** 仅在 guide/ 路径下启用图片缩放(首页用不上,避免 ~60KB 浪费) */
|
|
function isGuidePath(path: string): boolean {
|
|
return path.includes('/guide/') || path.startsWith('/en/guide/')
|
|
}
|
|
|
|
/** 移除 VitePress 默认注入的 Inter Web 字体 preload(我们用 system-ui 优先) */
|
|
function removeInterPreloads(): void {
|
|
if (typeof document === 'undefined') return
|
|
document.querySelectorAll('link[rel="preload"][as="font"][href*="/inter-"]').forEach((el) => {
|
|
el.remove()
|
|
})
|
|
// 移除字体 @font-face 规则(已经不用)
|
|
document.querySelectorAll('style').forEach((styleEl) => {
|
|
try {
|
|
if (styleEl.textContent && styleEl.textContent.includes('@font-face') && styleEl.textContent.includes('Inter')) {
|
|
styleEl.remove()
|
|
}
|
|
} catch {
|
|
// ignore CORS
|
|
}
|
|
})
|
|
}
|
|
|
|
/** 挂载时初始化 guide 图片缩放与字体清理 */
|
|
export function setupPageEnhance(): void {
|
|
const route = useRoute()
|
|
let zoom: { detach: () => void } | null = null
|
|
let zoomLoading = false
|
|
|
|
const initZoom = async () => {
|
|
if (!isGuidePath(route.path)) {
|
|
// 非 guide 页面,清理并跳过
|
|
if (zoom) {
|
|
zoom.detach()
|
|
zoom = null
|
|
}
|
|
return
|
|
}
|
|
if (zoomLoading) return
|
|
zoomLoading = true
|
|
try {
|
|
// 动态 import,首页不下载 medium-zoom ~60KB
|
|
const { default: mediumZoom } = await import('medium-zoom')
|
|
if (!isGuidePath(route.path)) return // 用户可能已经切走
|
|
if (zoom) zoom.detach()
|
|
await nextTick()
|
|
zoom = mediumZoom('.vp-doc img:not(.logo):not([alt*="badge"]):not([alt*="Badge"]):not([alt*="Stars"]):not([alt*="License"]):not([alt*="Python"]):not([alt*="NodeJS"]):not([alt*="MySQL"]):not([alt*="Redis"])', {
|
|
background: 'rgba(0, 0, 0, 0.8)',
|
|
margin: 24,
|
|
scrollOffset: 0,
|
|
})
|
|
} finally {
|
|
zoomLoading = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
// 异步执行,让首屏渲染先完成
|
|
requestIdleCallback?.(() => initZoom()) ?? setTimeout(() => initZoom(), 0)
|
|
// 移除 Inter 字体 preload(节省 68KB)
|
|
removeInterPreloads()
|
|
// 路由变化时也尝试移除(防止某些路径动态插入)
|
|
const observer = new MutationObserver(() => removeInterPreloads())
|
|
observer.observe(document.head, { childList: true, subtree: true })
|
|
// 路由切换时重新初始化
|
|
watch(() => route.path, () => {
|
|
initZoom()
|
|
removeInterPreloads()
|
|
})
|
|
// 卸载时释放观察器(防泄漏)
|
|
onUnmounted(() => observer.disconnect())
|
|
})
|
|
}
|