直接跳到内容

路由配置

介绍

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

步骤一:定义路由名

Demo 模块为例,路由常量定义在 core/navigation/src/main/ets/demo/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 网络请求示例页导航入口
 * @returns {void} 无返回值
 */
@Builder
export function NetworkDemoNav(): void {
  NetworkDemoPage();
}

步骤三:注册模块路由图

模块实现 RouteGraph 并注册路由。文件位置示例:feature/demo/src/main/ets/navigation/DemoGraph.ets

ts
import { RouteBuild, RouteGraph } from "navigation";
import { DemoRoutes } from "navigation/src/main/ets/demo/DemoRoutes";
import { NetworkDemoNav } from "./NetworkDemoNav";
import { NetworkRequestNav } from "./NetworkRequestNav";

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

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

模块 Index.ets 对外导出 Graph,入口模块统一注册。文件位置示例:feature/demo/Index.etsentry/src/main/ets/entryability/EntryAbility.ets

ts
/**
 * @file Demo 模块统一导出
 */
export { DemoGraph } from "./src/main/ets/navigation/DemoGraph";
ts
import { MainGraph } from "main";
import { AuthGraph } from "auth";
import { UserGraph } from "user";
import { DemoGraph } from "demo";

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

步骤五:使用模块级 Navigator(推荐)

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

文件位置示例:core/navigation/src/main/ets/demo/

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

/**
 * @file Demo 模块导航封装
 */
export class DemoNavigator {
  /**
   * 跳转到带参示例页
   * @param {number} goodsId - 商品 ID
   * @param {Resource} goodsName - 商品名称
   * @returns {void} 无返回值
   */
  static toNavigationWithArgs(goodsId: number, goodsName: Resource): void {
    const params: DemoGoodsParam = { goodsId, goodsName };
    navigateTo(DemoRoutes.NavigationWithArgs, params);
  }

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

DemoParam.etsDemoResult.ets 同步维护类型:

ts
/**
 * @file Demo 模块导航参数定义
 */

/**
 * 商品参数
 */
export interface DemoGoodsParam {
  /**
   * 商品 ID
   */
  goodsId: number;
  /**
   * 商品名称
   */
  goodsName: Resource;
}
ts
/**
 * @file Demo 模块导航返回结果定义
 */

/**
 * 结果回传对象
 */
export interface DemoResult {
  /**
   * 标题
   */
  title: string;
  /**
   * 说明
   */
  description: string;
}

建议

  • 统一用 Navigator 封装跳转,避免业务层直接拼路由名。
  • 所有路由参数与返回结果都用实体类型描述,避免 any

注意事项

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