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

如何在AutoRoute中使用多个App Router?Melos包结构路由跳转问题

跨包路由跳转解决方案(Melos多包结构)

问题核心:当前context.router是MyApp的路由实例,而MyGamesRoute属于Game包的AppRouter,两者路由实例不兼容导致跳转失败。以下是几种可行的解决方式:

方式一:主应用集成子包路由,通过回调传递跳转逻辑(推荐)

这种方式符合路由管理的最佳实践,将Game包的路由作为主应用路由的一部分,由主应用统一管理路由栈。

  1. 在MyApp的路由中集成Game包的路由
// apps/my_app/lib/router/app_router.dart
import 'package:game/router/game_router.dart';

class AppRouter extends RootStackRouter {
  @override
  List<RouteConfig> get routes => [
        // 主应用其他路由配置
        RouteConfig(
          GameRouter.name,
          router: GameRouter(), // 将Game包路由作为子路由集成
        ),
      ];
}
  1. 修改Game包的Banner组件,暴露跳转回调
    把跳转逻辑从Banner内部剥离,交给使用它的主应用处理:
// packages/game/lib/widgets/game_banner.dart
class GameBanner extends StatelessWidget {
  final bool tillStart;
  final VoidCallback onTapMyGames;

  const GameBanner({
    super.key,
    required this.tillStart,
    required this.onTapMyGames,
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTapMyGames,
      // Banner的UI实现
      child: /* ... */,
    );
  }
}
  1. 在MyApp中使用Banner时,触发主应用路由跳转
    通过主应用的路由实例跳转到Game包的路由节点:
// apps/my_app/lib/pages/home_page.dart
GameBanner(
  tillStart: tillStart,
  onTapMyGames: () async {
    // 直接跳转到Game路由的根节点
    await context.router.push(const GameRouterRoute());
    // 如果MyGamesRoute是Game路由的子页面,用嵌套跳转
    await context.router.push(
      GameRouterRoute(
        children: [MyGamesRoute(tillStart: tillStart)],
      ),
    );
  },
)

方式二:通过状态管理获取Game包的路由实例

如果需要在Game包内部处理跳转,可以通过状态管理(如Provider)提供路由实例,确保上下文能获取到正确的路由对象。

  1. Game包中创建路由实例的Provider
// packages/game/lib/router/game_router_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'game_router.dart';

final gameRouterProvider = Provider<GameRouter>((ref) => GameRouter());
  1. 在MyApp中确保Game路由实例已挂载
    在使用Banner的页面或父组件中,通过Router组件挂载Game的路由:
// apps/my_app/lib/pages/home_page.dart
final gameRouter = ref.watch(gameRouterProvider);

Scaffold(
  body: Router(
    routerDelegate: gameRouter.delegate(),
    routeInformationParser: gameRouter.defaultRouteParser(),
    child: GameBanner(
      tillStart: tillStart,
      onTap: () async {
        await gameRouter.push(MyGamesRoute(tillStart: tillStart));
      },
    ),
  ),
)

注意:这种方式需要确保Game的路由实例和主应用路由实例的生命周期协调,避免出现路由栈混乱的问题。

总结

优先选择方式一,它能让主应用统一管理所有路由,降低跨包耦合,同时保证路由栈的一致性和可维护性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:42:39