如何用GoRouter结合Bloc判断用户认证状态并跳转至对应页面
解决方案
1. 实现可监听的登录状态
先创建一个状态管理类,用来跟踪登录状态并通知路由更新:
class AuthState extends ChangeNotifier { bool _isLoggedIn = false; bool get isLoggedIn => _isLoggedIn; void login() { _isLoggedIn = true; notifyListeners(); } void logout() { _isLoggedIn = false; notifyListeners(); } }
2. 修改GoRouter配置,添加重定向逻辑
在路由配置中加入redirect规则和状态监听,根据登录状态自动跳转:
final AuthState _authState = AuthState(); GoRouter router() { return GoRouter( debugLogDiagnostics: true, refreshListenable: _authState, // 监听登录状态变化,自动触发重定向 redirect: (context, state) { final isLoggedIn = _authState.isLoggedIn; final isOnLoginPage = state.location == Routes.logIn.path; // 未登录且不在登录页,强制跳转到登录页 if (!isLoggedIn && !isOnLoginPage) { return Routes.logIn.path; } // 已登录且在登录页,跳转到ShellRoute的首页 if (isLoggedIn && isOnLoginPage) { return Routes.home.path; } // 其他情况保持原路由 return null; }, routes: _routes, ); } List<RouteBase> get _routes => <RouteBase>[ GoRoute( name: Routes.logIn.name, path: Routes.logIn.path, builder: (context, state) { return LogInScreen( onLoginSuccess: () => _authState.login(), // 登录成功后更新状态 ); }, ), ShellRoute( navigatorKey: _shellNavigatorKey, builder: (context, state, child) { return MainScreen(child: child); }, routes: <RouteBase>[ GoRoute( path: Routes.home.path, name: Routes.home.name, builder: (_, __) => const HomeScreen(), ), // 可在此添加更多底部导航对应的子路由 ], ), ];
3. 优化MyApp的Router实例复用
避免每次build都创建新的GoRouter实例,防止状态丢失:
final _appRouter = router(); class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return ScreenUtilInit( builder: (_, __) => MaterialApp.router( routerConfig: _appRouter, theme: AppTheme.lightTheme, ), ); } }
4. 登录页触发状态更新
在LogInScreen中完成登录逻辑后,调用状态更新方法:
class LogInScreen extends StatelessWidget { final VoidCallback onLoginSuccess; const LogInScreen({super.key, required this.onLoginSuccess}); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: ElevatedButton( onPressed: () { // 模拟登录接口请求 Future.delayed(const Duration(seconds: 1), () { onLoginSuccess(); }); }, child: const Text('登录'), ), ), ); } }
核心逻辑说明
redirect函数会在每次路由跳转前执行,根据登录状态动态调整跳转目标refreshListenable监听AuthState的变化,登录状态更新时会自动重新执行重定向逻辑- 无需直接跳转ShellRoute本身,跳转到它的子路由(如
Routes.home.path)就会自动加载ShellRoute对应的MainScreen容器
内容的提问来源于stack exchange,提问作者karim mesghouni
相关产品推荐
相关产品推荐

