Files
social-app/docs/bugs/路由守卫逻辑分散.md
T

2.4 KiB

路由守卫逻辑分散

问题描述

当前路由守卫逻辑分散在两处,可能导致判断不一致:

  1. app_router.dartredirect() - 核心守卫逻辑
  2. LinksyAppBlocListener - 预留了位置但未使用

当前代码

// app_router.dart
GoRouter createAppRouter(AuthBloc authBloc) {
  return GoRouter(
    refreshListenable: GoRouterRefreshStream(authBloc.stream),
    redirect: (context, state) {
      final authState = authBloc.state;
      final isAuthenticated = authState is AuthAuthenticated;
      // ... 守卫判断逻辑
    },
  );
}

// app.dart (LinksyApp)
BlocListener<AuthBloc, AuthState>(
  listener: (context, state) {
    // Handle auth state changes if needed  ← 预留但未使用
  },
)

问题

问题 说明
逻辑分散 守卫在 redirect(),但 BlocListener 预留了位置
隐患 将来可能有人在两处都加逻辑,导致不一致
职责不清 到底是 redirect 管跳转,还是 BlocListener 管跳转

建议方案

方案1:路由守卫集中在 redirect()(当前方案,保持但清理)

// app_router.dart
GoRouter createAppRouter() {
  return GoRouter(
    refreshListenable: GoRouterRefreshStream(sl<AuthBloc>().stream),
    redirect: (context, state) {
      // 唯一的守卫逻辑
    },
  );
}

// LinksyApp - 只做副作用,不做路由跳转
BlocListener<AuthBloc, AuthState>(
  listener: (context, state) {
    // 埋点、Toast 等副作用
  },
)

方案2:路由守卫集中在 BlocListener

// app_router.dart - 不再有 redirect
GoRouter createAppRouter() {
  return GoRouter(
    routes: [...],
  );
}

// LinksyApp - 唯一的路由守卫入口
BlocListener<AuthBloc, AuthState>(
  listener: (context, state) {
    final router = GoRouter.of(context);
    if (state is AuthUnauthenticated) {
      if (!isPublicRoute(router.matchedLocation)) {
        router.go(AppRoutes.authLogin);
      }
    } else if (state is AuthAuthenticated) {
      if (router.matchedLocation == AppRoutes.authLogin) {
        router.go(AppRoutes.homeMain);
      }
    }
  },
)

收益

收益 说明
单一职责 路由跳转只在一处判断
可维护 将来不会有人误在另一处加逻辑
清晰 开发者知道去哪改守卫逻辑

涉及文件

  • apps/lib/app/app.dart
  • apps/lib/app/router/app_router.dart

状态

  • 待修复