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

Flutter go_router:如何修改路由无需重启整个应用?

问题:go_router路由修改需重启应用,热重载无效的解决方案需求

我刚使用go_router包,之前用Navigator 1时,只需调用Navigator.push就能在栈中添加新页面,保存或热重载就能查看大部分修改,开发效率很高。但用go_router时,哪怕对路由做微小修改,都必须完全重启应用。比如调试12级深层路由问题时,每次修改都得从应用初始页面重新操作到目标页面,十分繁琐。

我目前的临时解决方法是在UI开发阶段用Navigator 1提升开发速度,但最终还要切换回go_router,这一过程很快就会让人疲惫。我期望修改路由(比如添加新路由或编辑pathParameter)后,仅需保存就能使修改生效。


main.dart代码

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  if (!BuildConfig.isDev) {
    ErrorWidget.builder = (FlutterErrorDetails details) => Container();
  }

  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then(
    (val) {
      runApp(
        ProviderScope(
          child: MyApp(),
        ),
      );
      FlutterError.demangleStackTrace = (StackTrace stack) {
        if (stack is stack_trace.Trace) return stack.vmTrace;
        if (stack is stack_trace.Chain) return stack.toTrace().vmTrace;
        return stack;
      };
    },
  );
}

class MyApp extends ConsumerWidget {
  MyApp({Key? key}) : super(key: key);

  final botToastBuilder = BotToastInit();
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final router = ref.watch(goRouterProvider);
    return MaterialApp.router(
      routerConfig: router,
      debugShowCheckedModeBanner: BuildConfig.isDev,
      title: AppInfo.title,
      themeMode: ThemeMode.light,
      
      theme: ThemeData(
          useMaterial3: true,
          scaffoldBackgroundColor: AppColors.canvas(context),
          primarySwatch: AppInfo.appPrimarySwatch,
          textTheme: GoogleFonts.figtreeTextTheme()),
      builder: botToastBuilder,
    );
  }
}

路由配置代码

final goRouterProvider = Provider<GoRouter>((ref) {
  return GoRouter(
    navigatorKey: AppGlobals.navigatorKey,
    initialLocation: RoutePath.root.path,
    observers: [BotToastNavigatorObserver()],
    redirect: (context, state) => null,
    routes: [
      GoRoute(
          path: RoutePath.root.path,
          name: RoutePath.root.name,
          builder: (context, state) => const SplashScreen(),
          routes: [
            GoRoute(
              path: RoutePath.welcome.path,
              name: RoutePath.welcome.name,
              builder: (context, state) => const WelcomeScreen(),
            ),
            GoRoute(
              path: RoutePath.enableLocation.path,
              name: RoutePath.enableLocation.name,
              builder: (context, state) => const EnableLocationServicesScreen(),
            ),
          ]),
      GoRoute(
          path: RoutePath.choices.path,
          name: RoutePath.choices.name,
          builder: (context, state) => const ChoiceScreen(),
          routes: [
            GoRoute(
              path: RoutePath.signUpPhone.path,
              name: RoutePath.signUpPhone.name,
              builder: (context, state) => const EnterPhoneNumberScreen(),
            ),
            GoRoute(
              path: RoutePath.enterPassword.path,
              name: RoutePath.enterPassword.name,
              builder: (context, state) => const CreatePasswordScreen(),
            ),
            GoRoute(
              path: RoutePath.verifyNumber.path,
              name: RoutePath.verifyNumber.name,
              builder: (context, state) {
                final isCode = state.extra ?? false;
                return VerifyPhoneScreen(
                  isCode: isCode as bool,
                );
              },
            ),
            GoRoute(
              path: RoutePath.resetPassword.path,
              name: RoutePath.resetPassword.name,
              builder: (context, state) => const ResetPasswordScreen(),
            ),
            GoRoute(
              path: RoutePath.forgotPassword.path,
              name: RoutePath.forgotPassword.name,
              builder: (context, state) => const ForgotPasswordScreen(),
            ),
            GoRoute(
              path: RoutePath.passwordSuccess.path,
              name: RoutePath.passwordSuccess.name,
              builder: (context, state) => const PasswordSuccessScreen(),
            ),
            GoRoute(
              path: RoutePath.uploadId.path,
              name: RoutePath.uploadId.name,
              builder: (context, state) => const UploadIDScreen(),
            ),
            GoRoute(
              path: RoutePath.propertyHome.path,
              name: RoutePath.propertyHome.name,
              builder: (context, state) => const CreatePasswordScreen(),
            ),
          ]),
      GoRoute(
        path: RoutePath.login.path,
        name: RoutePath.login.name,
        builder: (context, state) => const LoginScreen(),
      ),
      StatefulShellRoute.indexedStack(
          // parentNavigatorKey: shellNavKey,
          builder: (context, state, navigationShell) {
            return ScaffoldWithNestedNavigation(
              navigationShell: navigationShell,
              type: UserType.type,
            );
          },
          branches: baseBranches(AppGlobals.navigatorKey)),
    ],
  );
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 00:22:34