3、路由表设计:集中式路由表定义、路由路径命名规范、参数传递协议设计

路由表,说白了就是整个混合应用的路由「总台账」。

我见过不少团队,一开始图省事,每个页面各自维护跳转逻辑。结果项目到中期,跳转路径散落在十几个文件里,改个路径名要全局搜索,还经常漏改。嗯,这种痛,经历过的人都懂。

所以我的建议是:从一开始就搞集中式路由表。所有页面的路由定义、路径命名、参数协议,全部收拢到一个地方管理。

3.1 集中式路由表定义

集中式路由表,就是一个 JS/TS 对象或数组,把 App 里所有页面都注册进去。每个页面至少包含:path(路径)、name(页面标识)、component(页面组件)。

我个人习惯用 TypeScript 来定义,类型约束能提前发现很多低级错误。举个例子:

// router.config.ts
export interface RouteConfig {
  path: string;
  name: string;
  component: React.ComponentType<any>;
  meta?: {
    title?: string;
    needAuth?: boolean;
    keepAlive?: boolean;
  };
}

const routes: RouteConfig[] = [
  {
    path: '/home',
    name: 'Home',
    component: HomePage,
    meta: { title: '首页', needAuth: false }
  },
  {
    path: '/product/detail/:id',
    name: 'ProductDetail',
    component: ProductDetailPage,
    meta: { title: '商品详情', needAuth: true }
  },
  {
    path: '/user/profile',
    name: 'UserProfile',
    component: UserProfilePage,
    meta: { title: '个人中心', needAuth: true }
  }
];

export default routes;
核心要点:路由表是「单例」的,整个 App 只维护一份。Native 端和 H5 端都引用同一份配置,保证两端路径一致。

我在项目中遇到过一种情况:Android 和 iOS 各自维护了一套路由表,结果同一个页面在两端路径不同,联调时各种对不上。后来统一成集中式路由表,问题迎刃而解。

3.2 路由路径命名规范

路径命名看似小事,但规范不好,后期维护成本会直线上升。我总结了一套实践中比较好用的规范:

  • 全小写 + 连字符:比如 /user-profile 而不是 /userProfile/UserProfile。URL 对大小写敏感,全小写最安全。
  • 按模块分层:一级目录是业务模块,二级是具体页面。比如 /product/list/product/detail/:id
  • 参数用冒号占位:动态参数统一用 :paramName 格式,比如 /order/:orderId。不要用查询字符串传必填参数。
  • 避免过深嵌套:路径层级建议不超过 3 层。太深了不好记,也不好维护。
✅ 推荐 ❌ 不推荐 说明
/product/detail/:id /productDetail?id=xxx 路径参数比查询参数更清晰
/user/order/list /UserOrderListPage 全小写 + 分层,一目了然
/payment/result /pay/result/status/check 层级不超过 3 层
小技巧:可以在路由表里加一个 alias 字段,给常用页面起个简短别名。比如 /home 的别名是 /,方便快速跳转。

3.3 参数传递协议设计

参数传递是混合开发里最容易出幺蛾子的地方。Native 和 H5 对参数类型的理解不一样,很容易出现「iOS 传了字符串,Android 传了数字,H5 收到后解析失败」的情况。

我的做法是:统一参数协议。所有跨端传递的参数,都遵循以下规则:

  • 路径参数:只传简单类型(string、number)。比如 /product/detail/123,123 是商品 ID。
  • 查询参数:只传 string 类型。如果需要传对象,先 JSON.stringify 再传。
  • 复杂数据:通过 Bridge 或事件总线传递,不走 URL。比如用户信息、大 JSON 对象。

举个例子,商品详情页的参数传递:

// Native 端调用
const params = {
  id: 123,
  from: 'home_banner'
};
// 路径参数:/product/detail/123
// 查询参数:?from=home_banner
// 复杂数据:通过 Bridge 传递商品详情对象

// H5 端解析
const path = '/product/detail/123?from=home_banner';
const match = path.match(/\/product\/detail\/(\d+)\?from=(.+)/);
const id = match[1];        // "123"
const from = match[2];      // "home_banner"
注意:不要依赖 URL 传递敏感信息(如 token、密码)。URL 可能会被日志记录或缓存,存在安全风险。敏感数据走 Bridge 或加密通道。

我曾经踩过一个坑:某个版本把用户 ID 直接放在 URL 里,结果日志系统把 URL 全量打印了,导致用户 ID 泄露。从那以后,我规定所有敏感参数必须走 Bridge 传递。

3.4 路由表结构图

下面这张图展示了集中式路由表的整体结构,以及路径命名和参数传递的关系:

集中式路由表结构 路由表 (routes) path: "/home" name: "Home" meta: { title: "首页" } path: "/product/detail/:id" name: "ProductDetail" meta: { needAuth: true } path: "/user/profile" name: "UserProfile" meta: { keepAlive: true } path: "/payment/result" name: "PaymentResult" meta: { title: "支付结果" } 集中管理所有页面路由 路径命名规范 • 全小写 + 连字符 • 按模块分层 • 参数用 :param 占位 • 层级不超过 3 层 • 避免查询字符串传必填参数 参数传递协议 • 路径参数:简单类型 • 查询参数:string 类型 • 复杂数据:走 Bridge • 敏感数据:加密通道 • 统一 JSON 序列化 输出 ✅ 统一路径 ✅ 类型安全 ✅ 易于维护 ✅ 两端一致 ✅ 参数可追溯 ✅ 安全可控 ✅ 减少联调 ✅ 降低 Bug ✅ 新人上手快 ✅ 代码可读性强 ✅ 方便自动化

3.5 避坑指南

最后分享几个我实际踩过的坑,希望能帮你少走弯路:

  • 路径硬编码:不要在代码里直接写字符串路径。应该从路由表里引用常量,或者用路由生成函数。否则改路径时容易漏改。
  • 参数类型不一致:Native 端传数字,H5 端收到的是字符串。建议在路由解析层统一做类型转换。
  • 路由表膨胀:项目大了,路由表可能上千行。建议按模块拆分成多个文件,再合并到主路由表。
  • 忘记注册:新加页面后忘记注册路由,导致跳转白屏。可以在开发环境加一个路由校验工具,自动检测未注册的路径。
我的习惯:每次新增页面,先写路由配置,再写页面组件。顺序对了,就不容易漏。

集中式路由表,说白了就是「一次定义,到处使用」。前期多花半小时把规范定好,后期能省下数倍的排查时间。你想想看,是不是这个道理?