GoRouter是一个流行的包,用于Flutter中的声明式路由。它基于Navigator 2.0的API,支持深度链接和其他常见的导航场景,所有这些都在一个易于使用的API后面。
如果你是从Navigator 1.0来的,你会熟悉将路由推送到导航栈的概念。
但在使用GoRouter时,你有两个独立的选择。
- 前往一个路由
- 推送路线
本文将探讨这两者之间的区别,以便你能根据具体情况选择最合适的方式。
使用GoRouter的声明式路由
首先,让我们考虑一个简单的路由层次结构,由一个顶级路由和两个子路由组成。
GoRouter(
initialLocation: '/',
routes: [
// top-level route
GoRoute(
path: '/',
builder: (context, state) => const HomeScreen(),
routes: [
// one sub-route
GoRoute(
path: 'detail',
builder: (context, state) => const DetailScreen(),
),
// another sub-route
GoRoute(
path: 'modal',
pageBuilder: (context, state) => const MaterialPage(
fullscreenDialog: true,
child: ModalScreen(),
),
)
],
),
],
)
让我们也为我们的路由定义3个页面。
首页、详情页和模版页
从顶层路由进行导航
现在,假设我们在HomeScreen ,这只是一个有三个按钮的简单页面,其回调是这样定义的。
// onPressed callback for the first button
context.go('/detail'),
// onPressed callback for the second button
context.push('/detail'),
// onPressed callback for the third button
context.go('/modal'),
第一个和第二个回调具有相同的目标位置(/detail),因此它们的行为方式是相同的。
也就是说,在这两种情况下,我们最终会在导航栈中有两条路线**(首页→详情**)。
从主页到详细页
去和推之间的区别
从详情页,我们现在可以用两种不同的方式导航到/modal 。
// onPressed callback for the first button
context.go('/modal'),
// onPressed callback for the second button
context.push('/modal'),
从详情页到模式页
这一次的结果是不同的。
- 如果我们使用
go,我们最终会在主页的顶部出现模态页 - 如果我们使用
push,我们最终会将模态页面放在详细页面的顶部。
去和推是如何影响导航栈的
这是因为go ,通过放弃前一个路由(/detail )而跳到目标路由(/modal ),因为/modal 不是 /detail 的一个子路由。
有3条路线的路线层次结构:注意modal不是detail的子路线
同时,push 总是在现有路由的基础上添加目标路由,保留了导航栈。
这意味着,一旦我们取消了模态页面,我们就会导航回。
- 主页,如果我们使用
go - 详细页,如果我们使用了
push
这里有一个简短的视频展示了这种行为。
使用go vs push的路由:动画视频
这里有一个包含完整源代码的gist。
总结
底线是什么?
把go 作为一种跳转到新路线的方式。如果新路线不是旧路线的子路线,这将修改底层导航栈。
另一方面,push 将始终把目标路线推到现有的导航栈之上。
关于GoRouter的更多信息,请务必查看官方文档(它非常好)。