You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

flutter_modular 5.0.3导航异常:路由未找到与守卫异常排查

问题解决:flutter_modular子路由导航及守卫异常处理

核心问题拆解

  1. 导航路径错误:直接调用/tasks是根路径下的路由,而你的/tasks是RecruiterModule下的子路由,根路径不存在该路由;调用/recruiter/tasks触发守卫异常,因为模块级守卫会校验所有子路由,而你的守卫逻辑存在异步处理不及时、角色判断时机错误的问题。
  2. 守卫逻辑缺陷:
    • AuthGuard中触发bloc事件后直接返回当前状态,未等待异步状态更新完成
    • RoleGuardVerify在模块初始化时就判断用户状态,此时bloc可能还未完成初始化,导致守卫逻辑错误

解决方案

1. 正确的子路由导航方式

在RecruiterLandingPage中,使用相对路径导航到子路由,无需带上模块前缀:

// 正确写法:相对路径导航到当前模块的子路由
Modular.to.navigate('tasks');
// 或者显式相对路径
Modular.to.navigate('./tasks');

如果一定要用绝对路径,需要确保完整路径匹配模块路由+子路由,但相对路径更灵活,适配模块挂载路径变化。

2. 修复AuthGuard异步逻辑

修改AuthGuard,等待bloc状态加载完成后再判断登录状态:

import 'package:/authentication/ui/bloc/user_status/user_status_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:bloc/bloc.dart';

class AuthGuard extends RouteGuard {
  AuthGuard() : super();

  @override
  Future<bool> canActivate(String path, ModularRoute router) async {
    final bloc = Modular.get<UserStatusBloc>();
    // 只在未加载状态时触发加载
    if (bloc.state is! UserStatusLogin && bloc.state is! UserStatusLogout) {
      bloc.add(UserStatusLoadStarted());
    }
    // 等待状态变为登录或登出
    final state = await bloc.stream.firstWhere(
      (state) => state is UserStatusLogin || state is UserStatusLogout,
    );
    return state is UserStatusLogin;
  }
}

3. 重构RoleGuard逻辑

将角色判断逻辑移到RoleGuard的canActivate方法中,避免在模块初始化时提前判断状态:

修改RoleGuardVerify,返回带角色类型的RoleGuard即可:

import 'package:---/app/role_guard.dart';
import 'package:flutter_modular/flutter_modular.dart';

class RoleGuardVerify {
  static final int RECRUITER = 1;
  static final int CONSULTANT = 2;
  static final int MANAGER = 3;

  Map<int, String> redirectByRole = {
    RECRUITER: "/recruiter",
    CONSULTANT: "/consultant",
    MANAGER: "/manager"
  };

  RouteGuard getGuard(int guardRoleType) {
    // 直接返回RoleGuard,把判断逻辑放到RoleGuard内部
    return RoleGuard(guardRoleType);
  }
}

实现正确的RoleGuard:

import 'package:----/authentication/ui/bloc/user_status/user_status_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';

class RoleGuard extends RouteGuard {
  final int requiredRole;
  RoleGuard(this.requiredRole) : super();

  @override
  Future<bool> canActivate(String path, ModularRoute router) async {
    final bloc = Modular.get<UserStatusBloc>();
    // 确保状态已加载
    final state = await bloc.stream.firstWhere(
      (state) => state is UserStatusLogin || state is UserStatusLogout,
    );

    if (state is! UserStatusLogin) {
      Modular.to.navigate('/login');
      return false;
    }

    final user = (state as UserStatusLogin).user;
    // 判断用户角色是否匹配要求
    if (user.role == requiredRole) {
      return true;
    } else {
      // 根据角色重定向到对应模块
      final redirectPath = RoleGuardVerify().redirectByRole[user.role] ?? '/recruiter';
      Modular.to.navigate(redirectPath);
      return false;
    }
  }
}

4. 确保路由配置正确

确认RecruiterModule的路由结构无误:

// RecruiterModule的路由
@override
List<ModularRoute> get routes => [
  ChildRoute('/', child: (context, args) => RecruiterLandingPage(),
    children: [
      ChildRoute('/tasks',
        child: (context, args) => TasksPage(),
        transition: TransitionType.noTransition,
      ),
    ],
  ),
];

验证要点

  1. 导航时使用相对路径tasks,确保子路由在RouterOutlet中正确渲染
  2. 测试未登录状态下的重定向是否正常
  3. 测试不同角色用户访问时的重定向逻辑是否正确

内容的提问来源于stack exchange,提问作者Sahil Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 11:45:32