直接跳到内容

路由配置

介绍

路由配置的目标是让每个模块独立维护自己的路由入口,并在应用启动时统一注册。核心点只有三步:定义路由名、提供页面入口、注册路由图。

步骤一:定义路由名

路由常量可以定义在 feature 模块内部,也可以集中管理。以 Demo 模块为例:

文件位置:feature/demo/src/main/ets/navigation/DemoRoutes.ts

ts
/**
 * @file Demo 模块路由常量定义
 */
export const DemoRoutes = {
  /**
   * Network Demo 示例页路由
   */
  NetworkDemo: "demo/network-demo",
  /**
   * 通用网络请求示例页路由
   */
  NetworkRequest: "demo/network-request"
};

步骤二:页面入口 Builder

每个页面提供一个 @Builder 入口,用于路由构建。

文件位置:feature/demo/src/main/ets/navigation/NetworkDemoNav.ets

ts
import { NetworkDemoPage } from "../view/NetworkDemoPage";

/**
 * @file 网络请求示例页导航入口
 */
@Builder
export function NetworkDemoNav(): void {
  NetworkDemoPage();
}

步骤三:注册模块路由图

模块实现 RouteGraph 并注册路由。

文件位置:feature/demo/src/main/ets/navigation/DemoGraph.ets

ts
import { RouteBuild, RouteGraph } from "@core/navigation";
import { DemoRoutes } from "./DemoRoutes";
import { NetworkDemoNav } from "./NetworkDemoNav";
import { NetworkRequestNav } from "./NetworkRequestNav";

/**
 * @file Demo 模块路由图
 */
export class DemoGraph implements RouteGraph {
  /**
   * 注册 Demo 模块路由
   */
  register(): void {
    RouteBuild.register(DemoRoutes.NetworkDemo, wrapBuilder(NetworkDemoNav));
    RouteBuild.register(DemoRoutes.NetworkRequest, wrapBuilder(NetworkRequestNav));
  }
}

步骤四:导出 Graph 并在入口注册

模块 Index.ets 对外导出 Graph,入口模块统一注册。

模块导出

文件位置:feature/demo/Index.ets

ts
/**
 * @file Demo 模块统一导出
 */
export { DemoGraph } from "./src/main/ets/navigation/DemoGraph";

入口注册

文件位置:entry/src/main/ets/entryability/EntryAbility.ets

ts
import { MainGraph } from "@feature/main";
import { AuthGraph } from "@feature/auth";
import { UserGraph } from "@feature/user";
import { DemoGraph } from "@feature/demo";

/**
 * @file 入口 Ability 路由注册
 */
export default class EntryAbility {
  /**
   * 注册所有模块路由
   */
  registerRouter(): void {
    new MainGraph().register();
    new AuthGraph().register();
    new UserGraph().register();
    new DemoGraph().register();
  }
}

步骤五:使用业务 Navigator(推荐)

虽然可以直接调用 NavigationService,但更推荐通过 foundation/biz_navigation 的 Navigator 统一管理跳转。这样可以把路由名、参数类型和返回结果集中管理,避免 ViewModel 到处散落导航逻辑。

文件位置:foundation/biz_navigation/src/main/ets/demo/

  • DemoNavigator.ets:统一封装跳转方法
  • DemoParam.ets:统一定义参数类型
  • DemoResult.ets:统一定义返回类型
ts
import { navigateTo, navigateToForResult } from "../BusinessNavigationService";
import { DemoRoutes } from "./DemoRoutes";
import type { DemoResult } from "./DemoResult";

/**
 * @file Demo 模块导航封装
 */
export class DemoNavigator {
  /**
   * 跳转到带参示例页
   */
  static toNavigationWithArgs(goodsId: number, goodsName: Resource): void {
    navigateTo(DemoRoutes.NavigationWithArgs, { goodsId, goodsName });
  }

  /**
   * 跳转到结果回传示例页
   */
  static toNavigationResult(): Promise<DemoResult | undefined> {
    return navigateToForResult<DemoResult>(DemoRoutes.NavigationResult);
  }
}

参数类型

ts
/**
 * @file Demo 模块导航参数定义
 */
export interface DemoGoodsParam {
  goodsId: number;
  goodsName: Resource;
}

结果类型

ts
/**
 * @file Demo 模块导航返回结果定义
 */
export interface DemoResult {
  title: string;
  description: string;
}

在 ViewModel 中使用

ts
import { DemoNavigator } from "@foundation/biz-navigation";

@ObservedV2
export default class MainViewModel extends BaseViewModel {
  /**
   * 跳转到网络示例
   */
  goToNetworkDemo(): void {
    DemoNavigator.toNetworkDemo();
  }

  /**
   * 跳转并获取结果
   */
  async goToResultDemo(): Promise<void> {
    const result = await DemoNavigator.toNavigationResult();
    if (result) {
      console.log(result.title);
    }
  }
}

建议

  • 统一用 Navigator 封装跳转,避免业务层直接拼路由名。
  • 所有路由参数与返回结果都用实体类型描述,避免 any
  • Navigator 放在 foundation/biz_navigation,保持业务路由集中管理。

注意事项

  • 路由名称保持全局唯一,推荐按模块前缀命名(如 demo/xxx)。
  • Graph 只做注册,不写业务逻辑。
  • 页面入口使用 @Builder,避免在路由层直接处理状态。