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

如何在Flutter Web中通过go_router传递Repository对象至下一路由

在Flutter Web中用go_router复用Repository实例的方案

针对你的需求——在/customers路由创建Repo实例后,在/customers/:id路由复用同一实例,且支持F5刷新页面后仍能获取实例,推荐两种可靠方案:

方案一:单例模式(最简单高效)

直接将Repo设计为单例,确保整个应用生命周期内只有一个实例,刷新后也会复用该实例:

class Repo {
  // 私有构造函数,禁止外部直接创建实例
  Repo._();
  // 类级单例实例
  static final Repo instance = Repo._();

  // 工厂构造函数,简化调用方式
  factory Repo() => instance;

  void addEntity() {}
  void getEntity() {}
  void fetchEntities() {}
}

在Bloc中使用单例(支持传入自定义实例,方便测试):

class ListViewBloc {
  final Repo _repo;
  // 允许传入Mock实例,默认使用全局单例
  ListViewBloc({Repo? repo}) : _repo = repo ?? Repo();
}

class EditDialogBloc {
  final Repo _repo;
  EditDialogBloc({Repo? repo}) : _repo = repo ?? Repo();
}

go_router路由配置无需额外处理,正常跳转即可:

final router = GoRouter(
  routes: [
    GoRoute(
      path: '/customers',
      builder: (context, state) => CustomersPage(),
      routes: [
        GoRoute(
          path: ':id',
          builder: (context, state) => CustomerDetailPage(
            id: state.pathParameters['id']!,
          ),
        ),
      ],
    ),
  ],
);

方案二:全局依赖注入容器(适合复杂项目)

如果项目需要更灵活的依赖管理(比如多环境切换、动态替换实例),可以用get_it这类依赖注入库:

1. 初始化全局容器

final getIt = GetIt.instance;

2. 在列表路由注册Repo实例

进入/customers路由时初始化Repo,并注册为单例,避免重复创建:

class CustomersPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    if (!getIt.isRegistered<Repo>()) {
      getIt.registerSingleton<Repo>(Repo());
    }
    final repo = getIt<Repo>();
    final listBloc = ListViewBloc(repo: repo);

    return BlocProvider(
      create: (_) => listBloc,
      child: // 你的列表UI组件
    );
  }
}

3. 详情路由获取全局Repo

在/customers/:id路由中直接从容器获取实例,刷新时如果容器为空则兜底创建:

class CustomerDetailPage extends StatelessWidget {
  final String id;
  const CustomerDetailPage({required this.id, super.key});

  @override
  Widget build(BuildContext context) {
    final repo = getIt.isRegistered<Repo>() ? getIt<Repo>() : Repo();
    final editBloc = EditDialogBloc(repo: repo);

    return BlocProvider(
      create: (_) => editBloc,
      child: // 你的详情UI组件
    );
  }
}

关键注意事项

  • 不要用go_router的extra参数传递实例:Web页面刷新时extra参数会丢失,无法满足复用需求。
  • 单例模式适合简单场景,依赖注入容器适合复杂项目,可根据实际需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:33:34