是否可以使用与`GoRouter`的路由项和`ShellRoute`的路由项相同的`GoRoute`?

问题描述 投票:0回答:1

我有一个

GoRouter
:

GoRouter(
  navigatorKey: _rootNavigatorKey,
  routes: [
    GoRoute(
      path: '/login',
    ),
    ShellRoute(
      navigatorKey: _shellNavigatorKey,
      routes: [
        GoRoute(
          path: '/dashboard',
        ),
        // ... other routes
      ]
    ),
    GoRoute(
      parentNavigatorKey: _rootNavigatorKey,
      path: '/dashboard',
    ),
    // ... other routes
  ],
)

您可能会注意到,我在不同的地方使用相同的路线

/dashboard
(和类似的路线)。事实上,我可以从
BottomNavigationBar
Drawer
重定向到类似的路线。当我从
dashboard
转到
Drawer
时,我需要在
AppBar
上有一个后退按钮,因此我使用
go.push()
将路线放置在
ScaffoldWithNavigation
当前所选路线上方。

问题是是否可以在不同的路线集中使用相同的

GoRoute
(相同的
path
)?或者我应该使用不同的路线?

flutter dart router flutter-go-router
1个回答
0
投票

我决定按照 BambinoUA 的要求提供此答案。

以下是演示的相关代码片段:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter/foundation.dart' show kIsWeb;

class GoRouterMobile {
  static CustomTransitionPage noTransition(
    GoRouterState state,
    Widget page,
  ) {
    return CustomTransitionPage(
      key: state.pageKey,
      child: page,
      transitionDuration: Duration.zero,
      transitionsBuilder: (context, animation, secondaryAnimation, child) =>
          child,
    );
  }
}

final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();

final router = GoRouter(
  navigatorKey: _navigatorKey,
  initialLocation: '/',
  routes: <RouteBase>[
    GoRoute(
      path: '/',
      pageBuilder: (context, state) => GoRouterMobile.noTransition(
        state,
        Home(),
      ),
      routes: [
        GoRoute(
          path: 'page1', // for web browser purposes
          pageBuilder: (context, state) => GoRouterMobile.noTransition(
            state,
            Page1(),
          ),
          routes: [
            GoRoute(
              path: 'page2', // for web browser purposes
              pageBuilder: (context, state) => GoRouterMobile.noTransition(
                state,
                Page2(),
              ),
            ),
          ],
        ),
      ],
    ),
    GoRoute(
      path: '/page1', // for mobile app purposes
      pageBuilder: (context, state) => GoRouterMobile.noTransition(
        state,
        Page1(),
      ),
    ),
    GoRoute(
      path: '/page2', // for mobile app purposes
      pageBuilder: (context, state) => GoRouterMobile.noTransition(
        state,
        Page2(),
      ),
    ),
  ],
);

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('Home'),
            SizedBox(
              height: 8,
            ),
            ElevatedButton(
              onPressed: () {
                kIsWeb
                    ? context.go('///page1')
                    : GoRouter.of(context).push(Uri(path: '/page1').toString());
              },
              child: Text('Go to Page 1'),
            ),
          ],
        ),
      ),
    );
  }
}

class Page1 extends StatefulWidget {
  const Page1({super.key});

  @override
  State<Page1> createState() => _Page1State();
}

class _Page1State extends State<Page1> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          onPressed: () {
            if (GoRouter.of(context).canPop()) {
              GoRouter.of(context).pop();
            }
          },
          icon: Icon(CupertinoIcons.chevron_back),
        ),
        title: Text('Page 1'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('Page 1'),
            SizedBox(
              height: 8,
            ),
            ElevatedButton(
              onPressed: () {
                kIsWeb
                    ? context.go('///page1/page2')
                    : GoRouter.of(context)
                        .push(Uri(path: '/page2').toString());
              },
              child: Text('Go to Page 2'),
            ),
          ],
        ),
      ),
    );
  }
}

class Page2 extends StatefulWidget {
  const Page2({super.key});

  @override
  State<Page2> createState() => _Page2State();
}

class _Page2State extends State<Page2> {

  @override
  Widget build(BuildContext context) {
    return KeyboardDismissOnTap(
      dismissOnCapturedTaps: true,
      child: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            onPressed: () {
              if (GoRouter.of(context).canPop()) {
                GoRouter.of(context).pop();
              }
            },
            icon: Icon(CupertinoIcons.chevron_back),
          ),
          title: Text('Page 2'),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text('Page 2'),
              SizedBox(
                height: 8,
              ),
              ElevatedButton(
                onPressed: () {
                  context.go('/'); // to avoid having a page stack in the page cycle
                },
                child: Text('Go to Home'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

该代码最初专门用于移动应用程序,但我还决定包含

go_router
实现的 Web 行为。

这是网络运行时:

web

这是移动运行时:

mobile

代码片段解释:从上面的输出中可以看到,

go_route
层次结构引入了不同路由集中的路径。

您可以将其用作导航的参考,对于网络使用

context.go
(但视情况而定),对于移动设备使用
GoRouter.of(context).push

希望对你有帮助!

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.