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

Flutter Web单页应用如何用GoRouter实现固定侧边栏路由布局?

Flutter Web 实现固定侧边栏+动态内容的路由方案

要实现固定侧边栏、仅切换右侧内容的效果,你可以通过GoRouter的ShellRoute来实现,避免页面切换时侧边栏刷新。以下是具体修改方案:

1. 调整路由配置

使用ShellRoute将Dashboard作为外层容器(shell),子路由的页面作为动态内容嵌入其中:

final GoRouter _router = GoRouter(routes: <RouteBase>[
  GoRoute(
    path: '/',
    builder: (BuildContext context, GoRouterState state) {
      return const LoginScreen();
    },
  ),
  // 用ShellRoute包裹仪表盘和子路由
  ShellRoute(
    builder: (context, state, child) {
      // child 就是当前子路由对应的页面(HomeScreen/Home2Screen)
      return Dashboard(child: child);
    },
    routes: [
      // 访问/dashboard时默认跳转到home页面
      GoRoute(
        path: '/dashboard',
        redirect: (context, state) => '/dashboard/home',
      ),
      GoRoute(
        path: '/dashboard/home',
        builder: (context, state) => const HomeScreen(),
      ),
      GoRoute(
        path: '/dashboard/home2',
        builder: (context, state) => const Home2Screen(),
      ),
    ],
  ),
]);

2. 修改Dashboard组件

将子路由传入的页面作为右侧动态内容,侧边栏固定在左侧:

class Dashboard extends StatelessWidget {
  final Widget child;
  const Dashboard({super.key, required this.child});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: [
          const SideMenu(), // 固定侧边栏,不会随路由切换刷新
          Expanded(child: child), // 动态切换的内容区域
        ],
      ),
    );
  }
}

3. 侧边栏路由跳转

在SideMenu中直接使用GoRouter的跳转方法即可,比如:

// 跳转到home页面
TextButton(
  onPressed: () => context.go('/dashboard/home'),
  child: const Text('首页'),
),
// 跳转到home2页面
TextButton(
  onPressed: () => context.go('/dashboard/home2'),
  child: const Text('第二页'),
),

方案说明

  • ShellRoute的作用是让外层的Dashboard保持渲染状态,仅替换内部的child组件,这样侧边栏就不会随路由切换重新构建,避免了整体刷新的问题。
  • 相比在每个子页面重复添加侧边栏的方式,这种方案更符合路由嵌套的设计逻辑,代码复用性更高。

备选方案(手动判断路由)

如果不想使用ShellRoute,也可以通过监听当前路由路径手动切换内容,但这种方式需要维护路由与组件的映射,灵活性较低:

class Dashboard extends StatelessWidget {
  const Dashboard({super.key});

  @override
  Widget build(BuildContext context) {
    final currentPath = GoRouter.of(context).location;
    Widget content = const HomeScreen();
    
    if (currentPath == '/dashboard/home2') {
      content = const Home2Screen();
    }

    return Scaffold(
      body: Row(
        children: [
          const SideMenu(),
          Expanded(child: content),
        ],
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:45:35