Tại Sao Chọn GoRouter cho Ứng Dụng Web Flutter?
GoRouter, được phát triển bởi đội ngũ Flutter, được thiết kế để xử lý điều hướng theo cách dựa trên URL, điều này khiến nó trở nên lý tưởng cho các ứng dụng web. Dưới đây là lý do tại sao GoRouter lại nổi bật trong phát triển web Flutter:
- Điều Hướng Dựa Trên URL: GoRouter hỗ trợ các URL sạch (ví dụ:
/about,/product/123), phù hợp với cách người dùng mong đợi điều hướng trên web. - Tích Hợp Trình Duyệt: Nó xử lý các nút quay lại/tiến tới của trình duyệt và thay đổi URL một cách liền mạch.
- Liên Kết Sâu: Người dùng có thể chia sẻ hoặc đánh dấu các trang cụ thể (ví dụ:
/product/42) và đến trực tiếp trang đó. - Định Tuyến Tuyên Bố: Định nghĩa các tuyến đường một cách đơn giản, dễ mở rộng, giảm thiểu độ phức tạp trong điều hướng.
Trong hướng dẫn này, chúng ta sẽ xây dựng một ứng dụng web Flutter đơn giản với GoRouter, bao gồm một trang Chính, một trang Giới thiệu và một trang Sản phẩm với URL động. Chúng ta sẽ đảm bảo ứng dụng hỗ trợ điều hướng trình duyệt và liên kết sâu, trong khi giữ mã nguồn dễ tiếp cận cho người mới bắt đầu.
Thiết Lập Dự Án
Hãy cùng tạo một ứng dụng web Flutter với GoRouter từng bước.
Bước 1: Tạo Dự Án Flutter Mới
Nếu bạn chưa có dự án Flutter, hãy tạo một dự án mới bằng cách chạy:
flutter create go_router_web_app
cd go_router_web_app
Đảm bảo SDK Flutter của bạn được thiết lập cho phát triển web. Kiểm tra bằng cách:
flutter run -d chrome
Bước 2: Thêm Thư Viện GoRouter
Thêm gói go_router vào dự án của bạn. Mở pubspec.yaml và bao gồm:
dependencies:
go_router: ^16.2.1
Chạy flutter pub get để cài đặt. (Kiểm tra pub.dev để biết phiên bản mới nhất.)
Bước 3: Tạo Các Màn Hình Ứng Dụng
Chúng ta sẽ tạo ba màn hình đơn giản: HomeScreen, AboutScreen, và ProductScreen. Tạo một thư mục lib/screens và thêm các tệp sau đây.
lib/screens/home_screen.dart:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Trang Chính')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Chào mừng đến với Trang Chính!'),
ElevatedButton(
onPressed: () => context.go('/about'),
child: const Text('Đi đến Giới thiệu'),
),
ElevatedButton(
onPressed: () => context.go('/product/123'),
child: const Text('Xem Sản phẩm #123'),
),
],
),
),
);
}
}
lib/screens/about_screen.dart:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class AboutScreen extends StatelessWidget {
const AboutScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Giới thiệu')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Giới thiệu về Ứng dụng của Chúng tôi'),
ElevatedButton(
onPressed: () => context.go('/'),
child: const Text('Quay lại Trang Chính'),
),
],
),
),
);
}
}
lib/screens/product_screen.dart:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class ProductScreen extends StatelessWidget {
final String productId;
const ProductScreen({super.key, required this.productId});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Sản phẩm #$productId')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Chi tiết cho Sản phẩm #$productId'),
ElevatedButton(
onPressed: () => context.go('/'),
child: const Text('Quay lại Trang Chính'),
),
],
),
),
);
}
}
Bước 4: Thiết Lập GoRouter
Bây giờ, hãy cấu hình GoRouter để xử lý điều hướng. Thay thế nội dung của lib/main.dart bằng mã sau:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'screens/home_screen.dart';
import 'screens/about_screen.dart';
import 'screens/product_screen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// Định nghĩa cấu hình GoRouter
final GoRouter _router = GoRouter(
initialLocation: '/', // Bắt đầu tại trang chủ
routes: [
GoRoute(
path: '/',
builder: (context, state) => const HomeScreen(),
),
GoRoute(
path: '/about',
builder: (context, state) => const AboutScreen(),
),
GoRoute(
path: '/product/:productId',
builder: (context, state) {
final productId = state.pathParameters['productId']!;
return ProductScreen(productId: productId);
},
),
],
// Tùy chọn: Xử lý các lỗi giống như 404
errorBuilder: (context, state) => Scaffold(
appBar: AppBar(title: const Text('Trang Không Tìm Thấy')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Lỗi: ${state.error}'),
ElevatedButton(
onPressed: () => context.go('/'),
child: const Text('Đi đến Trang Chính'),
),
],
),
),
),
);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Demo Flutter GoRouter Web',
routerConfig: _router,
theme: ThemeData(primarySwatch: Colors.blue),
);
}
}
Giải Thích Mã
- Cài Đặt GoRouter: Chúng ta định nghĩa ba tuyến đường:
/: Liên kết vớiHomeScreen./about: Liên kết vớiAboutScreen./product/:productId: Liên kết vớiProductScreen, với tham số độngproductId.
- MaterialApp.router: Tích hợp GoRouter với hệ thống điều hướng của Flutter.
- Xử Lý Lỗi:
errorBuilderhiển thị trang 404 tùy chỉnh nếu người dùng điều hướng đến một tuyến đường không hợp lệ (ví dụ:/invalid). - Điều Hướng: Chúng ta sử dụng
context.go()để điều hướng, điều này cập nhật URL của trình duyệt và hỗ trợ các nút quay lại/tiến tới.
Bước 5: Chạy Ứng Dụng Trên Web
Chạy ứng dụng trong trình duyệt với:
flutter run -d chrome
Bạn sẽ thấy:
- Trang Chính với các nút để điều hướng đến Trang Giới thiệu hoặc Trang Sản phẩm.
- URL trong trình duyệt thay đổi thành
/,/about, hoặc/product/123khi bạn điều hướng. - Các nút quay lại/tiến tới của trình duyệt hoạt động liền mạch.
- Gõ một URL như
http://localhost:port/product/456trực tiếp trong trình duyệt sẽ đưa bạn đến Trang Sản phẩm với ID 456.
Các Tính Năng Chính Của GoRouter Cho Ứng Dụng Web
1. Điều Hướng Dựa Trên URL
GoRouter làm cho các URL trở thành cốt lõi của điều hướng. Ví dụ, điều hướng đến /product/123 với context.go('/product/123') cập nhật thanh địa chỉ của trình duyệt, làm cho URL có thể chia sẻ được.
2. Liên Kết Sâu
GoRouter hỗ trợ liên kết sâu ngay từ đầu. Nếu người dùng truy cập http://yourapp.com/product/123, GoRouter phân tích productId và tải màn hình chính xác. Điều này rất tuyệt vời cho việc chia sẻ liên kết hoặc tích hợp với các hệ thống bên ngoài như thông báo.
3. Tích Hợp Lịch Sử Trình Duyệt
GoRouter đồng bộ với lịch sử của trình duyệt. Nhấn nút quay lại sẽ quay lại tuyến đường trước đó (ví dụ: từ /about đến /), và tiến về phía trước. Điều này xảy ra tự động, không cần mã bổ sung.
4. Các Tuyến Đường Động
Cú pháp :productId cho phép các tuyến đường động. Bạn có thể truy cập tham số trong phần builder với state.pathParameters['productId']. Ví dụ:
GoRoute(
path: '/product/:productId',
builder: (context, state) => ProductScreen(productId: state.pathParameters['productId']!),
)
5. Tham Số Truy Vấn
GoRouter cũng hỗ trợ các tham số truy vấn (ví dụ: /search?query=flutter). Truy cập chúng với state.uri.queryParameters['query']. Ví dụ:
GoRoute(
path: '/search',
builder: (context, state) {
final query = state.uri.queryParameters['query'] ?? 'Không có truy vấn';
return SearchScreen(query: query);
},
)
6. Chuyển Hướng Cho Xác Thực
Đối với các ứng dụng web, bạn có thể muốn chuyển hướng người dùng đến trang đăng nhập nếu họ chưa xác thực. Thêm một chuyển hướng vào cấu hình GoRouter:
final GoRouter _router = GoRouter(
routes: [/* ... */],
redirect: (context, state) {
bool isLoggedIn = false; // Thay thế bằng logic xác thực của bạn
if (!isLoggedIn && state.uri.path != '/login') {
return '/login';
}
return null; // Không chuyển hướng
},
);
Mẹo Xây Dựng Ứng Dụng Web Flutter Thân Thiện URL
- Kiểm Tra URL Trực Tiếp: Thử gõ các URL như
/product/999trong trình duyệt để đảm bảo liên kết sâu hoạt động. - Sử Dụng Đường Dẫn Mô Tả: Giữ các tuyến đường như
/abouthoặc/producttrực quan cho người dùng. - Xử Lý Lỗi Một Cách Nhẹ Nhàng: Sử dụng
errorBuilderđể hiển thị các trang 404 thân thiện với người dùng. - Tối Ưu Hóa Cho SEO: Các URL sạch như
/product/123tốt hơn cho các công cụ tìm kiếm và việc chia sẻ. - Kiểm Tra Điều Hướng Trình Duyệt: Đảm bảo các nút quay lại/tiến tới hoạt động như mong đợi.
Triển Khai Ứng Dụng Web
Để triển khai ứng dụng web Flutter của bạn:
- Xây dựng nó bằng:
flutter build web
- Lưu trữ nội dung của thư mục
build/webtrên một máy chủ web (ví dụ: Firebase Hosting, Netlify, hoặc GitHub Pages). - Đảm bảo máy chủ của bạn hỗ trợ routing cho ứng dụng đơn, chuyển hướng tất cả các tuyến đường đến
index.htmlđể GoRouter có thể xử lý.