refactor: 重构 RouterContainer 组件以支持懒加载页面模块

- 移除不必要的 Suspense 组件,改为使用 LoadedPage 组件进行懒加载。
- 更新特性获取逻辑,使用 getFeatureByKey 函数替代直接查找。
- 新增 featureMeta.ts 文件,集中管理功能配置和相关方法。
- 实现 pageLoaders 以支持按需加载页面模块,提升性能和用户体验。
This commit is contained in:
2026-06-30 22:45:32 +08:00
parent d18ae5d41c
commit c7f4305fc3
17 changed files with 159 additions and 68 deletions
+47 -22
View File
@@ -1,11 +1,41 @@
import { FEATURES } from '@/config/features';
import { getFeatureByKey } from '@/config/features';
import { loadPage } from '@/config/pageLoaders/index';
import { useRouter } from '@/providers/RouterProvider';
import { Suspense } from 'react';
import type { PageType } from '@/types/storage';
import { type ComponentType, useEffect, useState } from 'react';
import PageErrorBoundary from '@/components/PageErrorBoundary';
import PageSkeleton from '@/components/PageSkeleton';
import { cn } from '@/lib/utils';
import { AlertTriangle } from 'lucide-react';
function LoadedPage({ pageKey }: { pageKey: PageType }) {
const [Page, setPage] = useState<ComponentType | null>(null);
useEffect(() => {
let cancelled = false;
loadPage(pageKey)
.then((mod) => {
if (!cancelled) {
setPage(() => mod.default);
}
})
.catch((err) => {
console.error('[Router Page Load Error]', err);
});
return () => {
cancelled = true;
};
}, [pageKey]);
if (!Page) {
return <PageSkeleton variant={pageKey === 'dashboard' ? 'dashboard' : 'tool'} />;
}
return <Page />;
}
export default function RouterContainer() {
const { currentPage, isLoaded } = useRouter();
@@ -16,8 +46,7 @@ export default function RouterContainer() {
return <PageSkeleton variant={currentPage === 'dashboard' ? 'dashboard' : 'tool'} />;
}
const currentFeature = FEATURES.find((f) => f.key === currentPage);
const MatchedComponent = currentFeature?.component;
const currentFeature = getFeatureByKey(currentPage);
return (
<div
@@ -28,25 +57,21 @@ export default function RouterContainer() {
animationClass,
)}
>
<Suspense
fallback={<PageSkeleton variant={currentPage === 'dashboard' ? 'dashboard' : 'tool'} />}
>
<PageErrorBoundary resetKey={currentPage}>
{MatchedComponent ? (
<MatchedComponent />
) : (
<div className="flex-1 flex flex-col items-center justify-center p-8 text-center animate-in fade-in duration-300">
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-destructive/10 text-destructive mb-4">
<AlertTriangle className="h-6 w-6" />
</div>
<h3 className="text-sm font-semibold text-foreground"></h3>
<p className="text-xs text-muted-foreground mt-1 max-w-[240px]">
</p>
<PageErrorBoundary resetKey={currentPage}>
{currentFeature ? (
<LoadedPage key={currentPage} pageKey={currentPage} />
) : (
<div className="flex-1 flex flex-col items-center justify-center p-8 text-center animate-in fade-in duration-300">
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-destructive/10 text-destructive mb-4">
<AlertTriangle className="h-6 w-6" />
</div>
)}
</PageErrorBoundary>
</Suspense>
<h3 className="text-sm font-semibold text-foreground"></h3>
<p className="text-xs text-muted-foreground mt-1 max-w-[240px]">
</p>
</div>
)}
</PageErrorBoundary>
</div>
);
}