refactor: 重构 RouterContainer 组件以支持懒加载页面模块
- 移除不必要的 Suspense 组件,改为使用 LoadedPage 组件进行懒加载。 - 更新特性获取逻辑,使用 getFeatureByKey 函数替代直接查找。 - 新增 featureMeta.ts 文件,集中管理功能配置和相关方法。 - 实现 pageLoaders 以支持按需加载页面模块,提升性能和用户体验。
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user