关于 flutter-bloc
面向 Flutter 开发者的 BLoC 状态管理规范,涵盖不可变事件与状态、异步流程、UI 职责、依赖注入和路由约定。
主要功能
- 01使用密封且不可变的事件与状态
- 02异步流程先加载再返回结果
- 03提供 BLoC 组件使用规范
- 04规定依赖注入方式
- 05规范路由与 Provider
- 06按功能组织目录结构
适用场景
- 01启动 Flutter BLoC 功能开发
- 02检查异步状态转换
- 03分离 UI 与业务逻辑
- 04组织路由和 BLoC Provider
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dhruvanbhalara/ skills --skill flutter-bloc安装后在 Claude Code 中输入/flutter-bloc确认已加载。
详细介绍
BLoC 模式
- 密封状态与事件:状态和事件都必须使用
sealed class,以确保 UI 处理完整,并在编译时保证安全。 - 不可变性:所有状态、事件和领域实体都必须不可变(使用
final和Equatable或freezed)。 - 官方 BLoC Part-Part Of 模式:每个
_bloc.dart文件都必须通过part指令引入对应的_event.dart和_state.dart文件。每个事件/状态文件都必须包含指向对应 BLoC 文件的part of指令,以确保它们处于同一库作用域并共享私有成员。// auth_bloc.dart part 'auth_event.dart'; part 'auth_state.dart'; class AuthBloc extends Bloc<AuthEvent, AuthState> { ... } // auth_event.dart part of 'auth_bloc.dart'; // auth_state.dart part of 'auth_bloc.dart'; - 强制目录结构:每组 BLoC 功能都必须位于
bloc/文件夹下独立的子目录中。严格禁止使用扁平的bloc/目录。presentation/bloc/ └── <bloc_name>/ ├── <bloc_name>_bloc.dart ├── <bloc_name>_event.dart └── <bloc_name>_state.dart - 加载状态要求:异步操作前必须始终发出
Loading,随后发出Success或Error。绝不能跳过加载状态。 - 并发处理:对于需要防抖(搜索)或节流(按钮)的事件,使用
transformers(例如restartable()、droppable())。 - UI 不含逻辑:Widget 不得包含业务逻辑、编排逻辑,也不得直接调用外部服务。它们只能分发事件,并根据 BLoC 状态构建 UI。
BLoC Widget 用法
- 使用
BlocBuilder根据状态局部重建 UI - 使用
BlocListener处理副作用(导航、snackbar、对话框) - 需要同时重建 UI 和处理副作用时,使用
BlocConsumer - 使用
context.read<Bloc>().add(Event())分发事件 - 使用
context.watch<Bloc>().state实现响应式重建(仅限build()内)
工作流:实现状态管理
添加或更新 BLoC 时,请遵循以下顺序执行工作流。复制此清单以跟踪进度。
任务进度
- 步骤 1:定义事件和状态。 确保它们使用
Equatable并设置正确的props,或使用freezed。 - 步骤 2:实现异步操作。 确认所有异步操作都遵循
Loading → Success/Error模式。 - 步骤 3:重构 UI。 确保 UI Widget 中不包含编排逻辑或业务逻辑;它们只能分发事件。
- 步骤 4:验证数据源。 确保所有 SDK/API 调用都只存在于 DataSources 中。
- 步骤 5:检查设计令牌。 确保没有使用硬编码的颜色、间距或字体排版。
- 步骤 6:格式化代码。 确保代码已使用
dart format格式化。
依赖注入
- 使用
injectable进行依赖注入和服务定位 - 标准化注入:
- 屏幕专用 BLoC 使用
@injectable,确保每次访问屏幕时都会创建新实例。 - 全局或共享 BLoC(例如
AuthBloc、ThemeBloc、SettingsBloc、PasswordBloc)使用@lazySingleton。
- 屏幕专用 BLoC 使用
- 按功能合理组织 BLoC,并确保严格分离关注点
导航与路由
- 动态路由:严格禁止在
GoRouter配置中硬编码路由字符串。请使用AppRoutes中的静态常量。 - 集中管理 BLoC:当多个屏幕或同一功能分支需要共享 BLoC 时,必须通过
app_router.dart中的ShellRoute或BlocProvider注入。 - 禁止本地 Provider:如果某个功能集需要使用 BLoC,请避免在单个屏幕的
build()方法中使用BlocProvider。 - 路由参数使用基本类型:严格禁止将复杂对象(BLoC、ChangeNotifiers、Entity 实例)作为路由参数传递。只传递基本类型的 ID/Key,并在目标屏幕中通过
Repository或 BLoC 注入获取数据。
评论
支持 Markdown