# Flutter 项目规范 > 严格遵循本文档定义的架构模式、状态管理标准和代码风格。未经授权不得引入新的第三方包或架构模式。优先组合而非继承,业务逻辑不进入 UI 组件。 --- ## 1. 技术栈 - **语言:** Dart(SDK >=3.0.0,严格空安全) - **框架:** Flutter(最新稳定通道) - **状态管理:** `flutter_riverpod`(v2.x,注解 + 代码生成) - **路由:** `go_router` - **网络请求:** `dio`(配合 `json_annotation` + `freezed` 进行 JSON 序列化) - **数据模型:** `freezed` + `build_runner` - **本地存储:** `hive` / `shared_preferences` - **依赖注入:** Riverpod Providers(不使用 GetIt) - **国际化:** `flutter_localizations`(l10n / ARB 格式) --- ## 2. 目录结构 采用 **特性优先架构(Feature-First)**,特性内部结合 **整洁架构(Clean Architecture)** 分层: ```text lib/ ├── app/ # 全局应用配置 │ ├── app.dart # MaterialApp 入口 │ ├── router/ # 路由定义(GoRouter) │ ├── theme/ # 主题、颜色、排版 │ └── constants/ # 全局常量、API 端点 │ ├── core/ # 跨特性共享代码 │ ├── network/ # Dio 客户端、拦截器、错误处理 │ ├── storage/ # 本地存储辅助工具 │ ├── utils/ # 辅助函数、扩展方法 │ └── widgets/ # 共享 UI 组件(按钮、输入框) │ ├── features/ # 特性模块 │ ├── auth/ # 示例:认证模块 │ │ ├── data/ # 数据源、API 端点、DTO │ │ ├── domain/ # 领域模型、仓库接口 │ │ └── presentation/ # UI 页面、组件、控制器 │ │ ├── controllers/ │ │ ├── pages/ │ │ └── widgets/ │ └── home/ # 示例:首页模块 │ ├── data/ │ ├── domain/ │ └── presentation/ │ ├── l10n/ # 国际化(.arb 文件) └── main.dart # 应用入口 ``` --- ## 3. 分层职责 ### 表示层(`presentation/`) UI 组件 + Riverpod Notifier / AsyncNotifier 控制器。 - 只能通过 `ref.watch` 或 `ref.listen` 消费状态。 - 禁止在 `onPressed` 或 `build()` 中直接调用 API 或编写业务逻辑。 ### 领域层(`domain/`) 纯 Dart 领域实体(`@freezed`)和仓库接口定义。 - 零 Flutter/UI 依赖。 ### 数据层(`data/`) 实现仓库接口,通过 Dio 处理 API 请求,将 JSON DTO 映射为领域实体。 --- ## 4. 编码规范 ### 状态管理(Riverpod) - 使用 `@riverpod` 注解 + `build_runner` 代码生成。 - 异步操作优先使用 `AsyncNotifierProvider`,配合 `AsyncValue`(Loading / Data / Error)。 ```dart @riverpod class UserProfileController extends _$UserProfileController { @override FutureOr build() async { return _fetchUser(); } Future updateName(String newName) async { state = const AsyncValue.loading(); state = await AsyncValue.guard( () => ref.read(userRepositoryProvider).updateName(newName), ); } } ``` ### 数据建模(freezed) 所有数据类/实体必须用 `freezed` 实现不可变,并配置嵌套 JSON 映射: ```dart import 'package:freezed_annotation/freezed_annotation.dart'; part 'user_model.freezed.dart'; part 'user_model.g.dart'; @freezed class UserModel with _$UserModel { const factory UserModel({ required String id, required String email, String? name, }) = _UserModel; factory UserModel.fromJson(Map json) => _$UserModelFromJson(json); } ``` ### UI 组件 - 尽可能使用 `const` 构造函数,避免不必要的重建。 - 复杂子树提取为独立私有/公有无状态组件,不要写冗长的内联辅助方法(如 `_buildHeader()`)。 - 响应式适配使用 `LayoutBuilder` / `MediaQuery` 或项目统一的屏幕适配工具。 --- ## 5. 命名约定 | 类别 | 规范 | 示例 | |---|---|---| | 文件/文件夹 | `snake_case.dart` | `user_profile.dart` | | 类/枚举 | `PascalCase` | `UserProfilePage` | | 变量/方法 | `camelCase` | `getUserData()` | | Provider | 以 `Provider` 结尾 | `userRepositoryProvider` | | 私有成员 | `_` 前缀 | `_handleTap()` | --- ## 6. 代码生成 修改或新增带代码生成的模型/控制器后,运行: ```bash # 一次性生成 flutter pub run build_runner build --delete-conflicting-outputs # 监听模式 flutter pub run build_runner watch --delete-conflicting-outputs ``` --- ## 7. 完成标准 - 新文件遵循特性优先结构。 - 代码为空安全、完全类型化,并进行 `const` 优化。 - 对应创建数据层、领域层和表示层组件。 - 不存在原始 `setState`(状态统一由 Riverpod 管理)。