navUtils.ts 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import { APP_ROUTE_METAS } from '@/defines/appRoutes';
  2. import { NAV_MENU_ITEMS } from '@/defines/navMenu';
  3. import { withLangPrefix } from '@/hooks/useAppNavigate';
  4. export interface NavMenuItem {
  5. name: string;
  6. /** 完整路径(含语言前缀,按渲染模式而定):SSG → /en/home;CSR → /home。 */
  7. path: string;
  8. locale?: string;
  9. }
  10. /** 渲染模式编译期常量(vite.config 的 define 注入),用于两套实现的编译期隔离。 */
  11. const isCSR = import.meta.env.VITE_RENDER_MODE === 'csr';
  12. // ————————————————————————————————————————————————————————————————
  13. // CSR 模式:从路由「纯数据」清单 APP_ROUTE_METAS 生成菜单(取 hideInMenu !== true 的项)。
  14. // 该清单不 import 任何组件,故不会牵出 routes.tsx→BasicLayout→Topbar 的循环依赖;
  15. // routes.tsx 与本文件共同消费这份清单,实现「路由与菜单单一数据源」。
  16. // ————————————————————————————————————————————————————————————————
  17. function getCsrMenuItems(): NavMenuItem[] {
  18. return APP_ROUTE_METAS.filter((meta) => meta.hideInMenu !== true).map((meta) => ({
  19. name: meta.name,
  20. path: `/${meta.path}`,
  21. locale: meta.locale,
  22. }));
  23. }
  24. // ————————————————————————————————————————————————————————————————
  25. // SSG 模式:读静态定义 src/defines/navMenu.ts,路径前缀由 withLangPrefix 按当前语言补齐。
  26. // framework 模式的路由源(src/routes.ts)是 route()/prefix() DSL,无 name/hideInMenu 可反推,
  27. // 故菜单独立声明于 navMenu.ts。
  28. // ————————————————————————————————————————————————————————————————
  29. function getSsgMenuItems(lang?: string): NavMenuItem[] {
  30. return NAV_MENU_ITEMS.map((item) => ({
  31. name: item.name,
  32. path: withLangPrefix(item.segment, lang),
  33. locale: item.locale,
  34. }));
  35. }
  36. /**
  37. * 获取导航菜单项。两种渲染模式各走各的来源,按编译期常量 VITE_RENDER_MODE 隔离:
  38. * - CSR:从 defines/appRoutes.ts 的路由清单派生(与 router/routes.tsx 同源)。
  39. * - SSG:读 defines/navMenu.ts 静态定义,withLangPrefix 补 /<lang> 前缀。
  40. *
  41. * 构建时非当前模式的分支会被 dead-code 消除。两套数据源都是纯数据、无组件依赖,不构成循环依赖。
  42. *
  43. * @param lang 当前语言短码(来自 useParams().lang)。仅 SSG 使用;CSR 忽略。
  44. */
  45. export function getNavMenuItems(lang?: string): NavMenuItem[] {
  46. if (isCSR) return getCsrMenuItems();
  47. return getSsgMenuItems(lang);
  48. }