关于 navigation
navigation 是一项 Flutter 应用路由技能,围绕 GoRouter 制定导航实践。它强调类型安全的层级路由、命名导航和适合深链的参数,并涵盖重定向与测试。
主要功能
- 01基于 GoRouter 的导航规范
- 02使用生成辅助代码的类型化路由
- 03层级化路由组织
- 04命名导航与 URL 参数
- 05重定向和组件测试指南
适用场景
- 01添加类型安全的 Flutter 路由
- 02组织页面以支持返回导航
- 03设置并测试深层链接
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ verygoodopensource/ vgv-ai-flutter-plugin --skill navigation安装后在 Claude Code 中输入/navigation确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/parameters.mdredirects.mdtesting.mdtyped-routes.md详细介绍
导航
使用 GoRouter 为 Flutter 应用进行路由和导航的最佳实践。GoRouter 是 Flutter 团队推荐的路由包,构建于 Navigator 2.0 API 之上。
核心规范
所有导航工作都应遵循以下规范:
- 所有导航都使用
package:go_router——绝不直接使用 Navigator 2.0 或 Navigator 1.0 的 push/pop - 使用
@TypedGoRoute注解定义类型安全路由 ——绝不在路由定义中使用原始字符串路径 - 优先使用
go()而非push()——仅在需要从目标页面接收返回数据时使用push() - 绝不使用
extra参数 ——它会破坏深层链接,且无法在 Web 上使用 - 使用层级子路由实现正确的返回导航 ——将路由组织成父子树,而非扁平列表
- 在 URL 中使用连字符分隔单词 ——绝不在 URL 路径中使用下划线或驼峰命名
- 通过路由名称导航,而非原始路径字符串 ——使用命名路由导航,以避免与路径变更耦合
- 使用
BuildContext扩展进行导航 ——优先使用context.goNamed(),而非GoRouter.of(context).goNamed()
路由组织
按照逻辑上的父子关系组织层级路由。子路由可确保应用栏的返回按钮正确显示,并使 URL 保持简洁。
层级结构(推荐)
/flutter
/flutter/news
/flutter/chat
/flutter/articles
/flutter/articles?category=all
/flutter/article/:id
/android
/android/news
/android/chat
扁平结构(避免)
/flutter-news
/flutter-chat
/android-news
/android-chat
层级子路由会自动实现正确的向后导航——当用户位于 /flutter/news 时,返回按钮会导航至 /flutter。
类型安全路由
每个路由都是带有 @TypedGoRoute 注解的 GoRouteData 类——绝不使用原始字符串路径。子路由嵌套在父路由的 routes: 列表中,从而在类型系统中表达上述层级结构,并由 package:go_router_builder 生成导航辅助方法。
有关基本路由、嵌套子路由和 Shell 路由,请参阅 references/typed-routes.md。
导航方法
go() 与 push() 的比较
| 方法 | URL 更新 | 返回按钮 | 适用场景 |
|---|---|---|---|
go() | 是 | 应用栏 | 页面之间的标准导航 |
push() | 否 | 系统 | 需要从弹出的路由接收返回数据时 |
使用 go()(默认)
const CategoriesPageRoute(size: 'small', color: 'blue').go(context);
使用 go() 可确保当当前路由存在可返回的父路由时,应用的 AppBar 中会显示返回按钮。
使用 push()(仅用于返回数据)
final result = await DialogPageRoute().push<String>(context);
仅在路由必须返回数据时使用 push()(例如,用于收集用户输入的对话框)。在 Web 上,push() 不会更新地址栏。
BuildContext 扩展
始终使用扩展方法,以简化语法:
// Preferred
context.goNamed('flutterNews');
// Avoid
GoRouter.of(context).goNamed('flutterNews');
参数策略
使用路径参数(:id)标识资源,使用查询参数(?category=all)进行可选筛选。绝不使用 extra ——它会破坏深层链接,且无法在 Web 上使用。
有关路径参数、查询参数的完整示例,以及禁止使用 extra 的原因,请参阅 references/parameters.md。
重定向
可在根路由器级别(例如身份验证守卫)和单个路由级别(例如授权守卫)应用重定向。父路由的重定向会先于子路由执行。
有关根级和路由级重定向示例,请参阅 references/redirects.md。
测试
使用 package:mocktail 模拟 GoRouter,并在组件测试中用 InheritedGoRouter 包装组件。通过构造包含目标重定向逻辑的 GoRouter 并断言最终页面来测试重定向。
有关模拟 GoRouter 和测试重定向的示例,请参阅 references/testing.md。
常见模式
添加新路由
- 创建页面组件(如果使用 Bloc,请遵循 Page/View 模式)
- 使用
@TypedGoRoute注解定义GoRouteData类 - 将其添加为适当父路由下的子路由
- 运行
dart run build_runner build --delete-conflicting-outputs,重新生成路由辅助代码 - 使用生成的类型安全路由类进行导航
深层链接设置
- 使用有意义的 URL 路径,以层级结构组织路由
- 使用路径参数标识资源
- 使用查询参数进行筛选,切勿使用
extra - 按路由名称进行导航,避免路径重构导致链接失效
- 使用目标 URL 启动应用,测试深层链接
其他资源
- references/parameters.md — 路径参数、查询参数,以及禁止使用
extra的原因 - references/redirects.md — 根级和路由级重定向示例
- references/typed-routes.md — 基本路由、嵌套子路由和 Shell 路由
- references/testing.md — 模拟
GoRouter并测试重定向