Skip to content

Flutter 路由:go_router / Navigator 体系

Flutter 路由的核心不是浏览器 URL,而是 内存中的页面栈 + 声明式/命令式导航策略

代码索引

主题Lab 说明源码
Navigator.pushNamed / pop(result) 基础路由flutter-routing-basicrouting_home_page.dart · routing_detail_page.dart
go_router 声明式路由 / redirect / path+query 参数flutter-routing-go-routergo_router_demo.dart

为什么需要

Flutter 项目里,路由问题很容易从“小功能”演变成“全局复杂度”:

  • 页面怎么跳
  • 参数怎么传
  • 返回值怎么回
  • 深链怎么接
  • 登录态拦截放哪
  • URL 同步与页面栈如何统一

如果只会 Navigator.push,到稍大一点的工程就会混乱。

底层机制

1. Navigator 本质是页面栈

Flutter 默认导航模型更接近:

text
push -> 入栈
pop  -> 出栈

所以:

  • 打开详情页,首页通常还在栈里
  • 返回时不是“重新创建整个 App”,而是回到上一层栈页面
  • 页面返回值可以直接通过 pop(result) 传回

2. 命令式 vs 声明式

命令式(Navigator 1.x 风格)

典型写法:

dart
Navigator.of(context).pushNamed('/detail');
Navigator.of(context).pop(result);

特点:

  • 上手快
  • 适合小型 demo 与简单业务流
  • 页面栈行为直观

声明式(Router / go_router)

典型思路:

  • 路由状态是“当前配置”
  • 页面树由路由状态推导
  • 更适合深链、重定向、嵌套路由、Web URL 同步

3. 参数与返回值是两条链路

  • 进入详情页:arguments / path / query 传入
  • 返回上一页:Navigator.pop(result) 回传

这两条链路不要混为一种“全靠全局状态”。

Android / Flutter / Web / Backend 对照

维度FlutterAndroidWebBackend
进入详情页Navigator.push/pushNamedstartActivity / NavControllerrouter.push请求进入子资源接口
返回上一页pop()finish() / back stack浏览器 back请求结束,无页面栈
传参arguments / path / queryIntent extras / nav argspath / queryrequest params
回传结果pop(result)Activity Result API常靠全局状态或 URLresponse body
栈管理内存页面栈Activity / Fragment back stack浏览器历史栈无 UI 栈

常见场景

1. 订单页跳详情,再回传操作结果

例如:

  • 首页打开订单详情
  • 详情页完成取消/确认动作
  • 返回首页后刷新指定条目

这时非常适合用 pop(result),而不是一开始就上全局事件总线。

对应 Labflutter-routing-basic · routing_home_page.dart · routing_detail_page.dart · flutter-routing-go-router · go_router_demo.dart

2. 登录态拦截

  • 小项目里容易散在每个按钮点击前判断
  • 稍大一些的项目应统一收敛到路由层(尤其 go_router redirect)

3. Web / H5 / App 对齐

如果项目有 WebView / H5 / Flutter 混合场景,就要提前想清:

  • 页面路径谁是事实源
  • query/path 参数怎么映射
  • 返回行为是否统一

常见坑

现象修法
把所有导航都写成匿名 MaterialPageRoute路由分散、难做统一治理集中 onGenerateRoute 或路由配置中心
参数全靠全局变量页面复用差、测试困难明确使用 arguments / path / query
页面返回后靠猜测刷新首页状态不稳定使用 await push... + pop(result)
一上来全项目硬上最复杂 go_router 嵌套路由理解成本高、改动重先把页面栈与参数/返回值模型吃透

与相近概念对比

概念适合场景优点风险
Navigator.push小功能、一次性跳转简单直接路由散落
pushNamed统一收敛命名路由中心化管理更好命名与参数约束要维护
go_router深链、redirect、嵌套路由适合中大型工程学习与配置成本更高
全局状态驱动导航跨模块事件流某些复杂流程可用容易隐式、难排查

对应实验

各章节内已嵌入跳转链接;此处汇总全部 Lab:

Lab说明源码
flutter-routing-basicflutter-routing-basicrouting_home_page.dart · routing_detail_page.dart
flutter-routing-go-routerflutter-routing-go-routergo_router_demo.dart

复习检查题

  1. Flutter 默认导航模型为什么更像“页面栈”而不是“浏览器 URL”?

    :因为默认 Navigator 维护的是内存中的 route stack,push 入栈、pop 出栈;页面返回更多是栈回退,而不是浏览器地址栏驱动。

  2. 为什么详情页结果回传优先考虑 pop(result)

    :因为它天然贴合页面栈语义,调用方可 await 得到结果,避免把简单回传问题上升成全局状态或事件总线。

  3. go_router 相比基础 Navigator 更适合什么场景?

    :更适合深链、登录态重定向、嵌套路由、Web URL 同步、多层路由治理等中大型工程场景。

速记

  • Navigator:页面栈
  • pushNamed:统一入口
  • pop(result):直接回传
  • 小场景先吃透栈模型
  • 大场景再上 go_router