插件介绍

go_router_builder 是一个为 go_router 提供的代码生成器,它通过 Dart 的注解和代码生成功能,帮助开发者构建类型安全的路由系统。这个包的核心价值在于将路由定义、参数解析和导航逻辑进行类型化,从而将运行时错误转化为编译时错误,提高代码质量和开发效率。
在这里插入图片描述

主要功能

  • 类型安全的路由定义:使用 Dart 类定义路由,确保参数类型正确
  • 自动生成导航代码:自动生成 gopushlocation 等导航方法
  • 参数处理自动化:自动处理路径参数、查询参数和额外参数
  • 支持复杂路由结构:支持嵌套路由、重定向、ShellRoute 等高级功能
  • 类型转换支持:自动处理基本类型和枚举类型的转换
  • 自定义过渡动画:支持自定义页面过渡效果

适用场景

  • 需要构建复杂路由结构的大型应用
  • 希望通过类型安全提高代码质量的项目
  • 希望减少路由相关样板代码的开发者
  • 需要支持深度链接和 Web 导航的跨平台应用

安装与配置

由于这是一个为鸿蒙平台定制的修改版本,我们需要通过 Git 形式引入依赖。

1. 添加依赖

在项目的 pubspec.yaml 文件中添加以下依赖配置:

dependencies:
  flutter:
    sdk: flutter
  go_router:
    git:
      url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
      path: "packages/go_router"
  go_router_builder:
    git:
      url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
      path: "packages/go_router_builder"

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner:
    ^2.3.0

2. 配置构建脚本

在项目根目录下创建或修改 build.yaml 文件,添加以下配置:

targets:
  $default:
    builders:
      go_router_builder:
        enabled: true

API 调用示例

下面通过一个完整的示例,展示如何在鸿蒙应用中使用 go_router_builder。

1. 定义路由数据类

创建 lib/routes.dart 文件,定义应用的路由结构:

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

// 导入生成的路由代码
part 'routes.g.dart';

// 主路由
<HomeRoute>(
  path: '/',
  routes: <TypedGoRoute<GoRouteData>>[
    TypedGoRoute<FamilyRoute>(
      path: 'family/:familyId',
      routes: <TypedGoRoute<GoRouteData>>[
        TypedGoRoute<PersonRoute>(
          path: 'person/:personId',
        ),
      ],
    ),
    TypedGoRoute<LoginRoute>(path: '/login'),
    TypedGoRoute<SettingsRoute>(path: '/settings'),
  ],
)
class HomeRoute extends GoRouteData {
  const HomeRoute();

  
  Widget build(BuildContext context, GoRouterState state) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () => const FamilyRoute(familyId: 'f1').go(context),
              child: const Text('View Family'),
            ),
            ElevatedButton(
              onPressed: () => const LoginRoute(from: '/').go(context),
              child: const Text('Login'),
            ),
            ElevatedButton(
              onPressed: () => const SettingsRoute().go(context),
              child: const Text('Settings'),
            ),
          ],
        ),
      ),
    );
  }
}

// 家族路由
class FamilyRoute extends GoRouteData {
  const FamilyRoute({required this.familyId});
  final String familyId;

  
  Widget build(BuildContext context, GoRouterState state) {
    return Scaffold(
      appBar: AppBar(title: Text('Family $familyId')),
      body: Center(
        child: ElevatedButton(
          onPressed: () => PersonRoute(familyId: familyId, personId: 'p1').go(context),
          child: const Text('View Person'),
        ),
      ),
    );
  }
}

// 人员路由
class PersonRoute extends GoRouteData {
  const PersonRoute({required this.familyId, required this.personId});
  final String familyId;
  final String personId;

  
  Widget build(BuildContext context, GoRouterState state) {
    return Scaffold(
      appBar: AppBar(title: Text('Person $personId')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Family ID: $familyId'),
            Text('Person ID: $personId'),
            ElevatedButton(
              onPressed: () => context.pop(),
              child: const Text('Back'),
            ),
          ],
        ),
      ),
    );
  }
}

// 登录路由
class LoginRoute extends GoRouteData {
  const LoginRoute({this.from});
  final String? from;

  
  Widget build(BuildContext context, GoRouterState state) {
    return Scaffold(
      appBar: AppBar(title: const Text('Login')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 登录成功后返回原页面或首页
            if (from != null) {
              context.go(from!);
            } else {
              const HomeRoute().go(context);
            }
          },
          child: const Text('Login'),
        ),
      ),
    );
  }
}

// 设置路由
class SettingsRoute extends GoRouteData {
  const SettingsRoute();

  
  Widget build(BuildContext context, GoRouterState state) {
    return Scaffold(
      appBar: AppBar(title: const Text('Settings')),
      body: const Center(
        child: Text('Settings Page'),
      ),
    );
  }
}

// 错误路由
class ErrorRoute extends GoRouteData {
  const ErrorRoute(this.error);
  final Exception error;

  
  Widget build(BuildContext context, GoRouterState state) {
    return Scaffold(
      appBar: AppBar(title: const Text('Error')),
      body: Center(
        child: Text('Error: ${error.toString()}'),
      ),
    );
  }
}

2. 生成路由代码

运行以下命令生成路由代码:

flutter pub run build_runner build --delete-conflicting-outputs

这将生成 lib/routes.g.dart 文件,包含所有自动生成的路由代码。

3. 配置路由

在应用的入口文件(如 lib/main.dart)中配置路由:

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'routes.dart';

void main() {
  runApp(const MyApp());
}

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

  
  Widget build(BuildContext context) {
    final router = GoRouter(
      routes: $appRoutes,
      initialLocation: '/',
      errorBuilder: (context, state) => ErrorRoute(state.error!).build(context),
    );

    return MaterialApp.router(
      title: 'GoRouter Builder Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routerConfig: router,
    );
  }
}

4. 使用导航功能

现在你可以使用类型安全的方式进行导航:

// 导航到家族页面
FamilyRoute(familyId: 'f1').go(context);

// 导航到人员页面
PersonRoute(familyId: 'f1', personId: 'p1').go(context);

// 带返回值的导航
final result = await PersonRoute(familyId: 'f1', personId: 'p1').push<String>(context);

// 获取路由位置
final location = PersonRoute(familyId: 'f1', personId: 'p1').location;
print(location); // 输出: /family/f1/person/p1

5. 高级功能示例

5.1 重定向
final router = GoRouter(
  routes: $appRoutes,
  redirect: (state) {
    final loggedIn = false; // 实际应用中从状态管理获取
    final loggingIn = state.matchedLocation == const LoginRoute().location;
    
    if (!loggedIn && !loggingIn) {
      return LoginRoute(from: state.matchedLocation).location;
    }
    if (loggedIn && loggingIn) {
      return const HomeRoute().location;
    }
    return null;
  },
);
5.2 自定义过渡动画
class FancyRoute extends GoRouteData {
  const FancyRoute();

  
  Widget build(BuildContext context, GoRouterState state) {
    return const Scaffold(
      body: Center(
        child: Text('Fancy Page'),
      ),
    );
  }

  
  MaterialPage<void> buildPage(BuildContext context, GoRouterState state) {
    return CustomTransitionPage<void>(
      key: state.pageKey,
      child: build(context, state),
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        return RotationTransition(
          turns: animation,
          child: child,
        );
      },
    );
  }
}
5.3 使用枚举类型
enum BookCategory {
  fiction,
  nonfiction,
  science,
}

<BooksRoute>(path: '/books')
class BooksRoute extends GoRouteData {
  const BooksRoute({this.category = BookCategory.fiction});
  final BookCategory category;

  
  Widget build(BuildContext context, GoRouterState state) {
    return Scaffold(
      appBar: AppBar(title: Text('Books - ${category.name}')),
      body: Center(
        child: Text('Category: ${category.name}'),
      ),
    );
  }
}

// 使用方式
BooksRoute(category: BookCategory.science).go(context);

鸿蒙平台注意事项

在鸿蒙平台上使用 go_router_builder 时,需要注意以下几点:

  1. 深度链接支持:鸿蒙平台对深度链接的支持可能与 Android 略有不同,需要确保在 module.json5 文件中正确配置路由规则。

  2. 性能优化:鸿蒙平台对应用性能有严格要求,建议合理使用路由缓存和懒加载功能。

  3. 资源管理:在使用复杂路由结构时,注意页面资源的释放,避免内存泄漏。

  4. 版本兼容性:确保使用与鸿蒙 SDK 兼容的 Flutter 版本和 go_router_builder 版本。

总结

go_router_builder 是一个强大的路由代码生成工具,它通过类型安全的方式帮助开发者构建高质量的路由系统。在鸿蒙平台上使用这个包,可以带来以下好处:

  1. 提高开发效率:减少路由相关的样板代码,自动生成导航方法
  2. 增强代码质量:将运行时错误转化为编译时错误,提高应用稳定性
  3. 支持复杂功能:轻松实现嵌套路由、重定向、ShellRoute 等高级功能
  4. 跨平台兼容:同时支持鸿蒙、Android、iOS 和 Web 平台

通过本文的介绍和示例,相信你已经对 go_router_builder 在鸿蒙平台上的使用有了全面的了解。这个工具不仅可以提高你的开发效率,还能帮助你构建更加健壮和可维护的应用。

如果你想深入了解更多高级功能,可以查看官方文档和示例项目,进一步探索 go_router_builder 的强大功能。

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐