flutter架 构项目基础

This commit is contained in:
崔宝新
2026-09-04 15:22:20 +08:00
parent 70967229d0
commit 0c5aee59c0
265 changed files with 35484 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
# 【Demo】详情页:参数接收的两种通道
> 源文件:`lib/pages/demo/detail_page.dart` | 分类:路由
> 一句话:构造参数与 ModalRoute arguments 双通道 —— 谁来了用谁,缺谁兜底。
---
## 一、这个 Demo 解决什么问题
同一个详情页,可能被两种方式打开:
- **方式 1**:`push` 构造传参(`DetailPage(name: '张三', age: 18)`);
- **方式 3**:`pushNamed` 命名路由 + arguments(`{'name': '李四', 'age': 25}`)。
页面要**同时兼容两种入口**:优先用 arguments 里的值,没有就用构造参数兜底。
---
## 二、怎么运行 / 演示内容
```dart
runApp(const RouterApp());
```
首页分别用方式 1 / 方式 3 跳进来,观察两种取参路径的效果。
---
## 三、核心知识点(新手向)
### 1. 构造参数(类型安全)
```dart
class DetailPage extends StatelessWidget {
const DetailPage({super.key, this.name = '默认', this.age = 0});
final String name;
final int age;
...
}
```
- 带默认值 → 不传参也能打开,不会崩;
- 类型安全:传错类型编译期报错。
### 2. 命名路由 arguments(运行期 Map)
```dart
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. 双通道合并取值(本页精髓)
```dart
Text('姓名:${argMap?['name'] ?? name}'),
Text('年龄:${argMap?['age'] ?? age}'),
```
"arguments 优先,构造参数兜底"——两种入口都兼容,缺参不崩。
---
## 四、关键代码剖析
```dart
// 手动 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](router_demo.md) 的 routes 表里。
---
## 六、扩展思考
- 选择器页 pop 带值见 [picker_page.md](picker_page.md);
- 参数多了建议封装成强类型对象(`class DetailArgs`),避免 Map 满天飞;
- 真实项目(go_router)用 `GoRoute` 的 `arguments` 或 `extra` 传对象,原理一致。