路由方案选型:主流混合路由方案对比
路由管理,说白了就是页面跳转的「交通指挥系统」。
我在做混合开发时,最头疼的不是业务逻辑,而是页面跳来跳去,参数传丢了、返回栈乱了、动画卡了……这些坑我踩过不少。今天咱们就聊聊 Flutter 里主流的四种路由方案,看看它们各自适合什么场景。
一、Fluro:轻量级的老牌选手
Fluro 是我最早接触的路由库。它很轻,API 也简单。
它的核心思路是「路径匹配 + 处理器」。你定义好路径,然后绑定一个处理器函数。跳转时,Fluro 根据路径找到对应的处理器,执行页面构建。
// Fluro 路由定义示例
var router = Router();
router.define("/user/:id", handler: Handler(
handlerFunc: (context, parameters) {
String userId = parameters['id'][0];
return MaterialPageRoute(
builder: (context) => UserPage(userId: userId),
);
},
));
嗯,这里要注意:Fluro 不支持类型安全的参数传递。参数都是字符串,你得自己解析。我在项目中遇到过传复杂对象时,只能序列化成 JSON 字符串,然后在目标页面再反序列化。说实话,挺麻烦的。
二、GetX:大而全的「瑞士军刀」
GetX 不只是路由,它还有状态管理、依赖注入、国际化……说白了,它是一个全家桶。
它的路由部分,我个人觉得最方便的是「命名路由 + 参数传递」的写法。你不需要手动创建 MaterialPageRoute,直接传参数就行。
// GetX 路由跳转示例
Get.toNamed("/user", arguments: {"id": "123", "name": "张三"});
// 目标页面接收参数
class UserPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final args = Get.arguments as Map<String, dynamic>;
return Text("用户ID: ${args['id']}");
}
}
我曾经在一个中型项目里用 GetX,确实开发效率很高。但后来发现一个问题:GetX 的路由和它的状态管理深度绑定,如果你后期想换状态管理方案,路由也得跟着换。这就有点「上了贼船」的感觉。
三、GoRouter:官方推荐的「正规军」
GoRouter 是 Flutter 官方团队维护的路由方案。它基于 Navigator 2.0 设计,支持声明式路由、深度链接、Web 路由等。
我个人习惯用 GoRouter,因为它类型安全、支持泛型参数传递,而且和 Flutter 生态结合得最好。
// GoRouter 路由配置示例
final router = GoRouter(
routes: [
GoRoute(
path: '/user/:id',
builder: (context, state) {
final userId = state.pathParameters['id']!;
return UserPage(userId: userId);
},
),
],
);
你想想看,GoRouter 的路径参数是类型安全的,state.pathParameters 返回的是 Map<String, String>,你不用担心类型转换出错。而且它还支持 extra 参数,可以传递任意类型的数据。
四、自定义 Router:自由但代价高
有些场景下,现成的路由方案满足不了需求。比如你需要复杂的页面过渡动画、自定义的返回栈逻辑、或者和原生端深度交互。
这时候,你可以基于 Navigator 2.0 自己实现一套路由管理。说白了,就是自己写一个 Router 类,管理页面栈、处理路由变化、监听返回事件。
// 自定义 Router 的简化示例
class MyRouter extends RouterDelegate<String> {
final List<Page<dynamic>> _pages = [];
@override
Widget build(BuildContext context) {
return Navigator(
pages: _pages,
onPopPage: (route, result) {
if (!route.didPop(result)) return false;
_pages.removeLast();
return true;
},
);
}
void pushPage(Page<dynamic> page) {
setState(() {
_pages.add(page);
});
}
}
我曾经在一个混合开发项目中,需要实现「原生页面和 Flutter 页面共享返回栈」。用 GoRouter 搞不定,最后只能自己写 Router。嗯,那段时间加班加得挺狠的。
五、选型决策矩阵
说了这么多,到底选哪个?我整理了一个决策矩阵,你对照着看就行。
| 评估维度 | Fluro | GetX | GoRouter | 自定义 Router |
|---|---|---|---|---|
| 类型安全 | ❌ 不支持 | ❌ 不支持 | ✅ 支持 | ✅ 可自行实现 |
| 参数传递 | 仅字符串 | 支持任意类型 | 支持泛型 | 完全可控 |
| 深度链接 | ❌ 不支持 | ❌ 不支持 | ✅ 原生支持 | 需自行实现 |
| Web 路由 | ❌ 不支持 | ❌ 不支持 | ✅ 原生支持 | 需自行实现 |
| 学习成本 | 低 | 中 | 中高 | 高 |
| 维护成本 | 低 | 中 | 低 | 高 |
| 社区活跃度 | 低(已停止维护) | 高 | 高(官方维护) | 无 |
| 推荐场景 | 快速原型 | 中小型项目 | 中大型项目 | 特殊需求 |
六、我的选型建议
如果你问我个人怎么选,我会这样排序:
- 首选 GoRouter:官方出品、类型安全、支持深度链接和 Web 路由。适合大多数项目。
- 次选 GetX:如果你已经在用 GetX 做状态管理,那路由也用它,省得引入新依赖。
- Fluro 可以放弃了:它已经停止维护,而且不支持类型安全。除非你维护的是老项目,否则别碰。
- 自定义 Router 是最后的选择:只有当你发现所有现成方案都满足不了需求时,才考虑自己写。