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

Flutter中GoRouter路径重定向异常:非根路径也被重定向至'/'?

问题原因分析

你的问题出在嵌套路由的使用方式错误:

你把/moon作为/的子路由,但父路由/的builder返回的SplashScreen并没有承载子路由内容的容器(比如Router组件或嵌套的Navigator)。当访问/moon时,GoRouter会先匹配父路由/,渲染SplashScreen,但子路由的CustomBar没有地方显示,导致你看到的始终是SplashScreen,看起来像是所有路径都被重定向到了/。

另外,如果你原本的需求是仅根路径/触发重定向逻辑(比如启动页自动跳转),当前的配置也不符合预期:你直接把/的页面设为SplashScreen,而没有用GoRouter的redirect机制来做条件重定向,这会导致所有嵌套子路由都会先加载父路由的SplashScreen。

解决方案

根据你的实际需求,有三种修正方式:

1. 不需要嵌套路由:让/和/moon成为同级路由

如果SplashScreen是独立的启动页,和/moon页面没有嵌套关系,直接把两个路由设为同级即可:

final GoRouter router = GoRouter(
  routes: <RouteBase>[
    GoRoute(
      path: '/',
      builder: (BuildContext context, GoRouterState state) {
        return SplashScreen();
      },
    ),
    GoRoute(
      path: '/moon',
      builder: (BuildContext context, GoRouterState state) {
        return CustomBar(indexTab: 4);
      },
    ),
  ],
);

这样访问/会显示SplashScreen,访问/moon会直接显示CustomBar,互不干扰。

2. 需要嵌套路由:给父路由页面添加子路由容器

如果确实需要SplashScreen作为父容器承载子路由内容,要在SplashScreen中添加Router组件来渲染子路由:

修改SplashScreen的代码:

class SplashScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 这里可以保留你的启动页UI元素,比如logo、加载动画等
      body: Column(
        children: [
          const Text('欢迎来到我的App'),
          // 子路由内容的承载区域
          Expanded(
            child: Router(
              routerDelegate: GoRouter.of(context).routerDelegate,
              backButtonDispatcher: GoRouter.of(context).backButtonDispatcher,
            ),
          ),
        ],
      ),
    );
  }
}

这样访问/moon时,SplashScreen会作为父页面,同时在指定区域显示CustomBar的内容。

3. 正确实现根路径重定向(如果你的需求是启动页自动跳转)

如果你的真实需求是:访问/时自动重定向到SplashScreen,完成启动后再跳转到主页,而其他路径直接访问对应页面,应该使用GoRouter的redirect配置:

// 假设你有一个全局变量标记启动流程是否完成
bool isAppInitialized = false;

final GoRouter router = GoRouter(
  redirect: (context, state) {
    // 仅当访问根路径且未初始化时,重定向到启动页
    if (state.location == '/' && !isAppInitialized) {
      return '/splash';
    }
    // 初始化完成后,访问根路径重定向到主页(可选)
    if (state.location == '/' && isAppInitialized) {
      return '/home';
    }
    // 其他路径不做重定向
    return null;
  },
  routes: <RouteBase>[
    GoRoute(
      path: '/splash',
      builder: (context, state) {
        return SplashScreen(
          // 在SplashScreen中完成初始化后更新isAppInitialized
          onInitialized: () {
            isAppInitialized = true;
            GoRouter.of(context).go('/home');
          },
        );
      },
    ),
    GoRoute(
      path: '/home',
      builder: (context, state) => HomePage(),
    ),
    GoRoute(
      path: '/moon',
      builder: (context, state) => CustomBar(indexTab: 4),
    ),
  ],
);

这种方式能精准控制只有根路径/会触发重定向逻辑,其他路径直接访问对应页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:13:20