Learn-skills.dev flutter-best-practices
Flutter 开发最佳实践指南,涵盖架构、依赖管理、UI 开发、平台配置。当用户提到"最佳实践"、"架构"、"Riverpod"、"GoRouter"、"Dio"、"主题"、"响应式"、"无障碍"时使用此 skill。
install
source · Clone the upstream repo
git clone https://github.com/NeverSight/learn-skills.dev
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/aidenreed937/comet/flutter-best-practices" ~/.claude/skills/neversight-learn-skills-dev-flutter-best-practices && rm -rf "$T"
manifest:
data/skills-md/aidenreed937/comet/flutter-best-practices/SKILL.mdsource content
Flutter Best Practices
确保 Flutter 代码遵循项目架构约定和最佳实践。
1. 环境与工具
| 配置项 | 要求 |
|---|---|
| Flutter channel | stable |
| Dart SDK | |
| 国际化 | (修改 arb 后执行) |
| 清理构建 | |
2. 依赖管理
核心依赖选型
| 功能 | 推荐库 | 用途 |
|---|---|---|
| 状态管理 | 3.x | Provider + StateNotifier |
| 路由 | 17.x | 声明式导航 |
| 网络 | 5.x | HTTP 客户端 + 拦截器 |
| 轻量存储 | | 非敏感 flags |
| 安全存储 | | 凭证/secrets |
| 结构化缓存 | + | 离线数据 |
依赖原则
# 检查过期依赖 flutter pub outdated # 保守升级(patch 级别) flutter pub upgrade --major-versions # 谨慎使用
- 使用 caret 约束(
)获取 patch 修复^x.y.z - 环境变量通过
传递,不硬编码--dart-define
3. 架构约定
目录结构
lib/ ├── app/ # 组合根 │ ├── di.dart # 核心服务 Provider │ └── router.dart # GoRouter 配置 ├── core/ # 基础设施(不导入 features) │ ├── config/ # 环境配置 │ ├── error/ # Failure + Result<T> │ ├── network/ # Dio + 拦截器 │ ├── storage/ # 存储封装 │ ├── theme/ # 主题定义 │ └── widgets/ # 通用组件 └── features/<name>/ # 功能模块 ├── presentation/ # UI + Provider ├── domain/ # 实体 + 接口(纯 Dart) └── data/ # 数据源 + 实现
层级规则
禁止导入core/features/
禁止导入domain/package:flutter- Feature 间通信通过
或共享接口core/services/
依赖注入
// app/di.dart - 核心服务 final dioClientProvider = Provider<DioClient>((ref) => DioClient()); // features/xxx/presentation/providers/ - 功能 Provider final xxxControllerProvider = StateNotifierProvider<XxxController, XxxState>(...);
路由配置
// features/xxx/presentation/routes.dart class XxxRoutes { static const xxx = '/xxx'; } List<GoRoute> buildXxxRoutes() => [ GoRoute(path: XxxRoutes.xxx, builder: (_, __) => const XxxPage()), ]; // app/router.dart final routerProvider = Provider<GoRouter>((ref) => GoRouter( routes: [...buildXxxRoutes(), ...buildYyyRoutes()], ));
错误处理
// 使用 Result<T> 替代 try-catch Future<Result<User>> getUser(String id) async { try { final response = await dio.get('/users/$id'); return Success(User.fromJson(response.data)); } on DioException catch (e) { return Err(NetworkFailure(e.message)); } } // UI 层处理 result.when( success: (user) => showUser(user), failure: (failure) => showError(failure.message), );
4. UI 最佳实践
Widget 设计
| 原则 | 说明 |
|---|---|
| 小而可组合 | 拆分 Page + 叶子组件 |
| 无状态优先 | 状态放 Riverpod,不放 StatefulWidget |
| const 构造 | 减少不必要的 rebuild |
| 主题引用 | 而非硬编码 |
样式规范
// ✅ 正确:从主题获取 final color = Theme.of(context).colorScheme.primary; final textStyle = Theme.of(context).textTheme.titleLarge; // ❌ 错误:硬编码 final color = Color(0xFF2196F3); final textStyle = TextStyle(fontSize: 22);
响应式布局
// 使用 LayoutBuilder 适配不同屏幕 LayoutBuilder( builder: (context, constraints) { if (constraints.maxWidth > 600) { return TabletLayout(); } return MobileLayout(); }, );
无障碍
| 要求 | 实现 |
|---|---|
| 点击区域 | 逻辑像素 |
| 图标语义 | 添加 标签 |
| 字体缩放 | 尊重 |
5. 平台配置
Android
<!-- AndroidManifest.xml - flutter_secure_storage 需要 --> <uses-permission android:name="android.permission.USE_BIOMETRIC" />
- Java 版本:17(CI 配置)
- Gradle lint:
./gradlew lint
iOS
# 本地开发 cd ios && pod install && open Runner.xcworkspace # CocoaPods 问题 pod repo update
6. 工作流清单
# 开发流程 flutter pub get # ... 实现功能 ... dart format --set-exit-if-changed . flutter analyze --fatal-infos flutter gen-l10n # 如有国际化变更 flutter test --coverage
7. 参考文档
| 库 | 文档 |
|---|---|
| Flutter SDK | https://docs.flutter.dev |
| flutter_riverpod | https://riverpod.dev/docs/getting_started |
| go_router | https://pub.dev/documentation/go_router/latest/ |
| dio | https://pub.dev/documentation/dio/latest/ |
| hive | https://docs.hivedb.dev/#/ |
| flutter_secure_storage | https://pub.dev/documentation/flutter_secure_storage/latest/ |
使用场景
- 新建 Feature: 遵循 presentation/domain/data 分层
- 添加依赖: 优先使用已选型的库
- 编写 UI: 无状态 + const + 主题引用
- 错误处理: 使用 Result<T> + Failure
- 平台适配: 检查 Manifest/Podfile 配置