路由管理
概述
本文档详细介绍了 FluCli 项目模板中的路由管理方案,包括基于 Flutter 原生路由和 GetX 路由的两种实现方式。通过本文档,您将了解如何在 FluCli 项目中进行页面导航、参数传递和路由配置。
📋 路由方案对比
特性 | Flutter 原生路由 | GetX 路由 |
---|---|---|
配置方式 | Map< String, WidgetBuilder > | List< GetPage > |
导航方法 | Navigator.pushNamed() | Get.toNamed() |
参数传递 | arguments 参数 | arguments + parameters |
路由拦截 | 需要自定义实现 | 内置中间件支持 |
代码复杂度 | 相对复杂 | 简洁易用 |
性能 | 原生性能 | 轻微性能开销 |
🚀 Flutter 原生路由
js
class RouterS {
/// 获取所有路由配置
static Map<String, WidgetBuilder> getAllRoutS() {
return {
RouterIdConfig.demo: (context) => const DemoV(),
RouterIdConfig.demoList: (context) => const DemoListV(),
...EgRouters.getRouters(),
};
}
/// 设置默认入口页
static configNoramlRouts() {
return RouterIdConfig.demo;
}
}
MaterialApp 配置
dart
Widget initMaterialApp({
Widget Function(BuildContext, Widget?)? builder,
required ThemeData theme,
}) {
return MaterialApp(
/// 全局导航键
navigatorKey: NavigatorUtil.navigatorKey,
/// 入口路由
initialRoute: RouterS.configNoramlRouts(),
/// 所有路由集合
routes: RouterS.getAllRoutS(),
/// 主题配置
theme: theme,
darkTheme: themeDataDark,
/// 页面构建器
builder: builder,
);
}
页面导航
dart
// 基础导航
Navigator.pushNamed(context, '/demo');
// 带参数导航
Navigator.pushNamed(
context,
'/demo',
arguments: {'id': 123, 'title': '示例'}
);
// 替换当前页面
Navigator.pushReplacementNamed(context, '/home');
// 清除所有页面并导航
Navigator.pushNamedAndRemoveUntil(
context,
'/home',
(route) => false,
);
参数获取
dart
class _DemoVState extends BaseStateV<DemoV> {
@override
void initState() {
super.initState();
// 获取路由参数
final arguments = ModalRoute.of(context)?.settings.arguments;
if (arguments != null && arguments is Map) {
final id = arguments['id'];
final title = arguments['title'];
// 处理参数...
}
}
}
⚡ GetX 路由
路由配置
在 hzy_basic_project
项目中,使用 GetX 的路由管理方式:
dart
class RouterS {
/// 获取所有路由配置
static List<GetPage<dynamic>> getAllRoutS() {
return [
GetPage(
name: RouterIdConfig.demo,
page: () => DemoV(),
),
GetPage(
name: RouterIdConfig.demoList,
page: () => DemoListV(),
),
...EgRouters.getRouters(),
];
}
/// 设置默认入口页
static configNoramlRouts() {
return RouterIdConfig.demo;
}
}
GetMaterialApp 配置
dart
Widget initMaterialApp({
Widget Function(BuildContext, Widget?)? builder,
}) {
return GetMaterialApp(
/// 入口路由
initialRoute: RouterS.configNoramlRouts(),
/// 所有路由集合
getPages: RouterS.getAllRoutS(),
/// 默认路由动画
defaultTransition: Transition.rightToLeft,
/// 主题配置
theme: themeDataLight,
darkTheme: themeDataDark,
/// 路由监听
navigatorObservers: [
AppRouterObserver().routeObserver,
],
builder: builder,
);
}
GetX 导航工具
dart
/// 跳转到指定界面
currentToPage({
required String name,
Map<String, String>? parameters,
dynamic arguments,
Function(Map info)? onChange,
bool preventDuplicates = true,
}) {
return Get.toNamed(
name,
parameters: parameters,
arguments: arguments,
preventDuplicates: preventDuplicates,
);
}
/// 底部弹出界面
bottomSheet({
required Widget body,
Color? barrierColor,
}) {
Get.bottomSheet(
body,
barrierColor: barrierColor ?? Colors.black.withOpacity(0.6),
exitBottomSheetDuration: const Duration(milliseconds: 300),
enterBottomSheetDuration: const Duration(milliseconds: 300),
isScrollControlled: true,
);
}
/// 弹出对话框
dialog({required Widget body}) {
Get.dialog(body);
}
GetX 页面导航
dart
// 基础导航
Get.toNamed('/demo');
// 带参数导航
Get.toNamed(
'/demo',
arguments: {'id': 123, 'title': '示例'},
parameters: {'type': 'detail'}
);
// 替换当前页面
Get.offNamed('/home');
// 清除所有页面并导航
Get.offAllNamed('/home');
// 返回上一页
Get.back();
// 返回并传递结果
Get.back(result: {'success': true});
GetX 参数获取
dart
class DemoV extends BaseGetXV<DemoC> {
@override
DemoC get controller => Get.put(DemoC());
@override
void onInit() {
super.onInit();
// 获取 arguments 参数
final arguments = Get.arguments;
if (arguments != null && arguments is Map) {
final id = arguments['id'];
final title = arguments['title'];
}
// 获取 parameters 参数
final type = Get.parameters['type'];
// 处理参数...
}
}
🔧 路由常用功能
路由拦截
GetX 路由拦截:
dart
GetPage(
name: '/protected',
page: () => ProtectedPage(),
middlewares: [
AuthMiddleware(), // 自定义中间件
],
);
class AuthMiddleware extends GetMiddleware {
@override
RouteSettings? redirect(String? route) {
// 检查用户是否登录
if (!UserService.isLoggedIn) {
return const RouteSettings(name: '/login');
}
return null;
}
}
原生路由拦截:
dart
class AppRouterDelegate extends RouterDelegate {
@override
Widget build(BuildContext context) {
// 自定义路由逻辑
if (!UserService.isLoggedIn) {
return LoginPage();
}
return HomePage();
}
}
路由动画
GetX 路由动画:
dart
GetPage(
name: '/demo',
page: () => DemoPage(),
transition: Transition.fadeIn,
transitionDuration: Duration(milliseconds: 300),
);
原生路由动画:
dart
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => DemoPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(opacity: animation, child: child);
},
),
);
📝 最佳实践
1. 路由常量管理
dart
class RouterIdConfig {
/// 主页
static const String demo = "/demo";
/// 列表页
static const String demoList = "/demo_list";
/// 详情页
static const String detail = "/detail";
}
2. 统一导航工具
dart
class NavigationUtil {
/// 跳转到详情页
static void toDetail(String id) {
// GetX 方式
Get.toNamed('/detail', arguments: {'id': id});
// 原生方式
// Navigator.pushNamed(context, '/detail', arguments: {'id': id});
}
/// 返回首页
static void toHome() {
// GetX 方式
Get.offAllNamed('/home');
// 原生方式
// Navigator.pushNamedAndRemoveUntil(context, '/home', (route) => false);
}
}
3. 路由参数类型安全
dart
// 定义参数模型
class DetailPageArguments {
final String id;
final String title;
DetailPageArguments({required this.id, required this.title});
}
// 使用类型安全的参数传递
NavigationUtil.toDetail(DetailPageArguments(
id: '123',
title: '示例标题',
));
🎯 选择建议
使用 Flutter 原生路由的场景:
- 项目对性能要求极高
- 团队更熟悉 Flutter 原生 API
- 需要与现有原生路由系统集成
- 项目规模较小,路由逻辑简单
使用 GetX 路由的场景:
- 希望简化路由管理代码
- 需要丰富的路由功能(中间件、动画等)
- 项目已使用 GetX 状态管理
- 快速开发和原型验证