使用GoRouter的Flutter导航|Go vs Push

948 阅读3分钟

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的更多信息,请务必查看官方文档(它非常好)。