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;
我在项目中遇到过一种情况: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"
我曾经踩过一个坑:某个版本把用户 ID 直接放在 URL 里,结果日志系统把 URL 全量打印了,导致用户 ID 泄露。从那以后,我规定所有敏感参数必须走 Bridge 传递。
3.4 路由表结构图
下面这张图展示了集中式路由表的整体结构,以及路径命名和参数传递的关系:
3.5 避坑指南
最后分享几个我实际踩过的坑,希望能帮你少走弯路:
- 路径硬编码:不要在代码里直接写字符串路径。应该从路由表里引用常量,或者用路由生成函数。否则改路径时容易漏改。
- 参数类型不一致:Native 端传数字,H5 端收到的是字符串。建议在路由解析层统一做类型转换。
- 路由表膨胀:项目大了,路由表可能上千行。建议按模块拆分成多个文件,再合并到主路由表。
- 忘记注册:新加页面后忘记注册路由,导致跳转白屏。可以在开发环境加一个路由校验工具,自动检测未注册的路径。
集中式路由表,说白了就是「一次定义,到处使用」。前期多花半小时把规范定好,后期能省下数倍的排查时间。你想想看,是不是这个道理?