Files
App.K12.Student.Miniapp_Flu…/docs/demos/detail_page.md
T
2026-09-04 15:22:20 +08:00

2.7 KiB
Raw Blame History

【Demo】详情页:参数接收的两种通道

源文件:lib/pages/demo/detail_page.dart | 分类:路由 一句话:构造参数与 ModalRoute arguments 双通道 —— 谁来了用谁,缺谁兜底。


一、这个 Demo 解决什么问题

同一个详情页,可能被两种方式打开:

  • 方式 1:push 构造传参(DetailPage(name: '张三', age: 18));
  • 方式 3:pushNamed 命名路由 + arguments({'name': '李四', 'age': 25})。

页面要同时兼容两种入口:优先用 arguments 里的值,没有就用构造参数兜底。


二、怎么运行 / 演示内容

runApp(const RouterApp());

首页分别用方式 1 / 方式 3 跳进来,观察两种取参路径的效果。


三、核心知识点(新手向)

1. 构造参数(类型安全)

class DetailPage extends StatelessWidget {
  const DetailPage({super.key, this.name = '默认', this.age = 0});

  final String name;
  final int age;
  ...
}
  • 带默认值 → 不传参也能打开,不会崩;
  • 类型安全:传错类型编译期报错。

2. 命名路由 arguments(运行期 Map)

final args = ModalRoute.of(context)?.settings.arguments;
final argMap = args is Map<String, dynamic> ? args : null;
  • ModalRoute.of(context) 拿到当前路由 → .settings.arguments 取出 pushNamed 传的参数;
  • arguments 是 dynamic,必须判空强转:
    • 不是 Map(或没传)→ argMap 为 null;
    • argMap?['name'] 取不到时用 ?? name 回退构造参数。

3. 双通道合并取值(本页精髓)

Text('姓名:${argMap?['name'] ?? name}'),
Text('年龄:${argMap?['age'] ?? age}'),

"arguments 优先,构造参数兜底"——两种入口都兼容,缺参不崩。


四、关键代码剖析

// 手动 pop(AppBar 的返回箭头也是 pop,效果一样)
OutlinedButton(
  onPressed: () => Navigator.pop(context),
  child: const Text('返回上一页'),
)

五、踩坑记录

  1. arguments 是 dynamic,直接用会崩(args['name'] 对非 Map 类型运行期报错)——先 is Map 判断;
  2. ModalRoute.of(context)?.settings.arguments 有 ?,路由可能为 null;
  3. 构造参数给默认值,保证"零参数也能打开页面"(debug 直达页面时很有用);
  4. 命名路由注册在 router_demo.md 的 routes 表里。

六、扩展思考

  • 选择器页 pop 带值见 picker_page.md;
  • 参数多了建议封装成强类型对象(class DetailArgs),避免 Map 满天飞;
  • 真实项目(go_router)用 GoRoute 的 arguments 或 extra 传对象,原理一致。