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

