Skip to Content

GoRouter - Declarative Navigation

1. Giới thiệu

GoRouter là package navigation hiện đại cho Flutter:

  • Type-safe routing
  • Deep linking support
  • Web URL support
  • Declarative API
# pubspec.yaml dependencies: go_router: ^12.0.0

2. Setup cơ bản

Định nghĩa Router

final router = GoRouter( initialLocation: '/', routes: [ GoRoute( path: '/', builder: (context, state) => HomeScreen(), ), GoRoute( path: '/profile', builder: (context, state) => ProfileScreen(), ), GoRoute( path: '/settings', builder: (context, state) => SettingsScreen(), ), ], );

Sử dụng trong MaterialApp

MaterialApp.router( routerConfig: router, )

3. Navigate

go - Navigate và replace stack

context.go('/profile');

push - Add to stack

context.push('/profile');

pop - Go back

context.pop();

replace - Replace current

context.replace('/home');

Visualizing Navigation Stack

Khác biệt giữa go, pushreplace:

1. context.go('/b') Stack: [/a] ──▶ Stack: [/b] (Thay thế hoàn toàn stack cũ nếu cần) 2. context.push('/b') Stack: [/a] ──▶ Stack: [/a, /b] (Thêm vào đỉnh stack) 3. context.replace('/b') Stack: [/a] ──▶ Stack: [/b] (Thay thế route hiện tại)

4. Path Parameters

GoRoute( path: '/user/:id', builder: (context, state) { final userId = state.pathParameters['id']!; return UserScreen(userId: userId); }, ), // Navigate context.go('/user/123');

5. Query Parameters

GoRoute( path: '/search', builder: (context, state) { final query = state.uri.queryParameters['q'] ?? ''; return SearchScreen(query: query); }, ), // Navigate context.go('/search?q=flutter');

6. Extra Data

Truyền object phức tạp:

// Navigate với extra context.go('/product', extra: Product(id: 1, name: 'iPhone')); // Nhận trong route GoRoute( path: '/product', builder: (context, state) { final product = state.extra as Product; return ProductScreen(product: product); }, ),

7. Nested Routes

GoRoute( path: '/shop', builder: (context, state) => ShopScreen(), routes: [ GoRoute( path: 'products', // /shop/products builder: (context, state) => ProductsScreen(), routes: [ GoRoute( path: ':id', // /shop/products/123 builder: (context, state) { final id = state.pathParameters['id']!; return ProductDetailScreen(id: id); }, ), ], ), GoRoute( path: 'cart', // /shop/cart builder: (context, state) => CartScreen(), ), ], ),

8. Redirect - Auth Guard

final router = GoRouter( redirect: (context, state) { final isLoggedIn = authService.isLoggedIn; final isLoggingIn = state.matchedLocation == '/login'; if (!isLoggedIn && !isLoggingIn) { return '/login'; // Redirect to login } if (isLoggedIn && isLoggingIn) { return '/'; // Redirect to home } return null; // No redirect }, routes: [...], );

9. ShellRoute - Persistent UI

Bottom navigation bar persistent across routes:

ShellRoute( builder: (context, state, child) { return Scaffold( body: child, bottomNavigationBar: BottomNavigationBar( items: [ BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'), BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'), BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'), ], currentIndex: _calculateSelectedIndex(state), onTap: (index) => _onItemTapped(index, context), ), ); }, routes: [ GoRoute(path: '/', builder: (_, __) => HomeScreen()), GoRoute(path: '/search', builder: (_, __) => SearchScreen()), GoRoute(path: '/profile', builder: (_, __) => ProfileScreen()), ], ),

10. Error Handling

final router = GoRouter( errorBuilder: (context, state) { return Scaffold( body: Center( child: Text('Page not found: ${state.uri}'), ), ); }, routes: [...], );

11. Ví dụ đầy đủ

class AppRouter { static final router = GoRouter( initialLocation: '/', redirect: _guard, errorBuilder: (context, state) => NotFoundScreen(), routes: [ GoRoute( path: '/login', builder: (context, state) => LoginScreen(), ), ShellRoute( builder: (context, state, child) => MainShell(child: child), routes: [ GoRoute( path: '/', builder: (context, state) => HomeScreen(), ), GoRoute( path: '/products', builder: (context, state) => ProductsScreen(), routes: [ GoRoute( path: ':id', builder: (context, state) { final id = state.pathParameters['id']!; return ProductDetailScreen(id: id); }, ), ], ), GoRoute( path: '/profile', builder: (context, state) => ProfileScreen(), ), ], ), ], ); static String? _guard(BuildContext context, GoRouterState state) { final isLoggedIn = context.read<AuthProvider>().isLoggedIn; if (!isLoggedIn && state.matchedLocation != '/login') { return '/login'; } return null; } } // main.dart void main() { runApp( MaterialApp.router( routerConfig: AppRouter.router, ), ); }

📝 Tóm tắt

MethodMô tả
context.go()Navigate, thay thế stack
context.push()Navigate, thêm vào stack
context.pop()Quay lại
context.replace()Replace current route
FeatureMô tả
Path params/user/:id
Query params/search?q=...
Extra dataObject phức tạp
RedirectAuth guards
ShellRoutePersistent UI
Last updated on