GoRouter 是 Flutter 官方推薦的 declarative router。路由定義集中在一個 GoRouter 物件中,導航操作用 URL path 表達(context.go('/terminal')),支援 deep link、redirect、和巢狀路由。

路由定義

GoRouter 的路由定義是一棵樹,每個節點是一個 GoRoute,指定 path 和 builder。

1GoRouter(routes: [
2  GoRoute(path: '/', builder: (context, state) => HomeScreen()),
3  GoRoute(path: '/enrollment', builder: (context, state) => EnrollmentScreen()),
4  GoRoute(path: '/terminal', builder: (context, state) => TerminalScreen()),
5]);

路由定義是 app 所有可到達畫面的完整清單。新增畫面時先在路由定義中加入 path,再實作 builder。路由定義同時也是路由可達性檢查的 source of truth(路由可達性)。

導航 API

GoRouter 提供三個主要的導航方法,語意不同,適用場景不同。

context.go(path)

替換整個導航堆疊。go('/terminal') 讓使用者直接到 terminal 畫面,按 back 不會回到前一個畫面(堆疊已被替換)。

適合場景:切換主要工作區。從登入畫面到首頁(登入成功後使用者不應該按 back 回到登入畫面)。

context.push(path)

把新畫面推入導航堆疊。push('/enrollment') 讓使用者到 enrollment 畫面,按 back 回到前一個畫面。

適合場景:暫時離開做一件事,做完回來。從首頁到配對畫面,配對完成後按 back 回首頁。

context.pushReplacement(path)

替換堆疊頂端的畫面。不改變堆疊深度 — 前一個畫面被新畫面取代,按 back 回到更早的畫面。

適合場景:步驟式流程中的前進。步驟 1 → pushReplacement 步驟 2 → pushReplacement 步驟 3。使用者在步驟 3 按 back 不會回到步驟 2(已被替換),而是回到流程開始前的畫面。

Redirect 機制

GoRouter 的 redirect 在每次導航前執行,可以根據 app 狀態(登入狀態、權限)把使用者導向不同畫面。

1GoRouter(
2  redirect: (context, state) {
3    final isLoggedIn = authState.isLoggedIn;
4    if (!isLoggedIn && state.matchedLocation != '/login') return '/login';
5    if (isLoggedIn && state.matchedLocation == '/login') return '/';
6    return null; // 不 redirect
7  },
8  routes: [...],
9);

Redirect 集中管理「什麼條件下使用者不能到某個畫面」的邏輯。比在每個畫面的 initState 中各自檢查更容易維護和測試。

ShellRoute(巢狀導航)

ShellRoute 讓多個畫面共享同一個外殼(tab bar、bottom navigation、drawer)。子路由的導航在 shell 內發生,shell 本身不變。

1ShellRoute(
2  builder: (context, state, child) => ScaffoldWithNavBar(child: child),
3  routes: [
4    GoRoute(path: '/home', builder: ...),
5    GoRoute(path: '/search', builder: ...),
6    GoRoute(path: '/profile', builder: ...),
7  ],
8)

ShellRoute 適合 tab bar 導航模式 — 底部的 tab bar 是 shell,每個 tab 的內容是子路由。

下一步路由