go_router
和 auto_route
实现复杂路由与拦截在 Flutter 中,随着应用规模的增长,路由管理变得越来越复杂。简单的 Navigator
和命名路由可能难以满足需求,比如嵌套路由、动态路由参数、路由守卫(如登录验证)等。为了解决这些问题,Flutter 社区提供了强大的第三方路由库,如 go_router
和 auto_route
。
本篇博客将深入探讨如何使用 go_router
和 auto_route
实现复杂路由管理,并结合实际场景实现路由拦截(如登录验证)。
go_router
实现复杂路由管理go_router
?go_router
是一个轻量级的路由库,专为 Flutter 设计,支持嵌套路由、动态路由参数和路由守卫。
go_router
在 pubspec.yaml
中添加依赖:
dependencies:
go_router: ^6.0.0
运行以下命令安装依赖:
flutter pub get
使用 GoRouter
配置路由表:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final GoRouter _router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomePage(),
),
GoRoute(
path: '/details/:id',
builder: (context, state) {
final id = state.params['id']!;
return DetailsPage(id: id);
},
),
],
);
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router,
);
}
}
class HomePage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("首页")),
body: ListView(
children: [
ListTile(
title: Text("详情页 1"),
onTap: () => context.go('/details/1'),
),
ListTile(
title: Text("详情页 2"),
onTap: () => context.go('/details/2'),
),
],
),
);
}
}
class DetailsPage extends StatelessWidget {
final String id;
DetailsPage({required this.id});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("详情页")),
body: Center(
child: Text("详情页 ID: $id"),
),
);
}
}
GoRouter
:定义路由表,配置路径和页面。state.params
获取动态参数。context.go
:实现页面跳转。在电商应用中,商品详情页可能包含多个子页面(如商品信息、评论、推荐)。
final GoRouter _router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomePage(),
routes: [
GoRoute(
path: 'details/:id',
builder: (context, state) {
final id = state.params['id']!;
return DetailsPage(id: id);
},
routes: [
GoRoute(
path: 'reviews',
builder: (context, state) => ReviewsPage(),
),
],
),
],
),
],
);
context.go('/details/1/reviews');
某些页面(如购物车、订单)需要登录后才能访问。
bool isLoggedIn = false;
final GoRouter _router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomePage(),
),
GoRoute(
path: '/cart',
builder: (context, state) => CartPage(),
redirect: (context, state) {
if (!isLoggedIn) {
return '/login';
}
return null;
},
),
GoRoute(
path: '/login',
builder: (context, state) => LoginPage(),
),
],
);
redirect
:在路由跳转前检查登录状态。auto_route
实现复杂路由管理auto_route
?auto_route
是一个功能强大的路由库,支持代码生成、嵌套路由和路由守卫。
auto_route
在 pubspec.yaml
中添加依赖:
dependencies:
auto_route: ^5.0.0
auto_route_generator: ^5.0.0
dev_dependencies:
build_runner: ^2.0.0
运行以下命令安装依赖:
flutter pub get
使用 @MaterialAutoRouter
注解定义路由表:
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
(
routes: <AutoRoute>[
AutoRoute(page: HomePage, initial: true),
AutoRoute(page: DetailsPage),
],
)
class $AppRouter {}
运行以下命令生成路由代码:
flutter pub run build_runner build
final _appRouter = AppRouter();
Widget build(BuildContext context) {
return MaterialApp.router(
routerDelegate: _appRouter.delegate(),
routeInformationParser: _appRouter.defaultRouteParser(),
);
}
class AuthGuard extends AutoRouteGuard {
final bool isLoggedIn;
AuthGuard(this.isLoggedIn);
void onNavigation(NavigationResolver resolver, StackRouter router) {
if (isLoggedIn) {
resolver.next(true); // 允许导航
} else {
router.push(LoginRoute()); // 跳转到登录页面
}
}
}
(
routes: <AutoRoute>[
AutoRoute(page: HomePage, initial: true),
AutoRoute(page: CartPage, guards: [AuthGuard]),
AutoRoute(page: LoginPage),
],
)
class $AppRouter {}
go_router
实现bool isLoggedIn = false;
final GoRouter _router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomePage(),
),
GoRoute(
path: '/details/:id',
builder: (context, state) {
final id = state.params['id']!;
return DetailsPage(id: id);
},
),
GoRoute(
path: '/cart',
builder: (context, state) => CartPage(),
redirect: (context, state) {
if (!isLoggedIn) {
return '/login';
}
return null;
},
),
GoRoute(
path: '/login',
builder: (context, state) => LoginPage(),
),
],
);
go_router
和 auto_route
的对比
go_router
:轻量级,适合快速开发。auto_route
:功能强大,适合复杂项目。高级功能
项目实战