BLoC (Business Logic Component) 是 Flutter 中一种流行的状态管理架构,它可以帮助你将业务逻辑与 UI 分离,使代码更清晰、可测试性更强。
核心概念
1. BloC 的核心组件
- Events:用户交互或系统事件(如按钮点击、网络请求完成)
- States:应用的状态表示(如加载中、数据加载成功、错误)
- Bloc:处理事件并发出新状态的业务逻辑组件
2. 数据流
UI → Event → BloC → State → UI
基础实现步骤
1. 添加依赖
在 pubspec.yaml
中添加:
dependencies:flutter_bloc: ^8.1.3bloc: ^8.1.2
运行 flutter pub get
2. 创建基本结构
定义事件 (Events)
// counter_event.dart
abstract class CounterEvent {}class IncrementEvent extends CounterEvent {}class DecrementEvent extends CounterEvent {}
定义状态 (States)
// counter_state.dart
class CounterState {final int count;CounterState(this.count);
}
创建 BloC
// counter_bloc.dart
import 'package:bloc/bloc.dart';class CounterBloc extends Bloc<CounterEvent, CounterState> {CounterBloc() : super(CounterState(0)) {on<IncrementEvent>((event, emit) {emit(CounterState(state.count + 1));});on<DecrementEvent>((event, emit) {emit(CounterState(state.count - 1));});}
}
3. 在 UI 中使用
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget { Widget build(BuildContext context) {return MaterialApp(home: BlocProvider(create: (context) => CounterBloc(),child: CounterPage(),),);}
}class CounterPage extends StatelessWidget { Widget build(BuildContext context) {final counterBloc = BlocProvider.of<CounterBloc>(context);return Scaffold(appBar: AppBar(title: Text('BLoC Counter')),body: Center(child: BlocBuilder<CounterBloc, CounterState>(builder: (context, state) {return Text('Count: ${state.count}',style: TextStyle(fontSize: 24),);},),),floatingActionButton: Column(mainAxisAlignment: MainAxisAlignment.end,children: [FloatingActionButton(onPressed: () => counterBloc.add(IncrementEvent()),child: Icon(Icons.add),),SizedBox(height: 10),FloatingActionButton(onPressed: () => counterBloc.add(DecrementEvent()),child: Icon(Icons.remove),),],),);}
}
进阶用法
1. 处理异步操作
// 在 BloC 中处理异步事件
on<LoadDataEvent>((event, emit) async {emit(LoadingState());try {final data = await repository.fetchData();emit(DataLoadedState(data));} catch (e) {emit(ErrorState(e.toString()));}
});
2. 使用 BlocObserver 调试
void main() {Bloc.observer = SimpleBlocObserver();runApp(MyApp());
}class SimpleBlocObserver extends BlocObserver {void onChange(BlocBase bloc, Change change) {super.onChange(bloc, change);print('${bloc.runtimeType} $change');}
}
3. 多个 BloC 的使用
return MultiBlocProvider(providers: [BlocProvider<CounterBloc>(create: (context) => CounterBloc()),BlocProvider<ThemeBloc>(create: (context) => ThemeBloc()),],child: MyApp(),
);
最佳实践
- 保持 BloC 简单:每个 BloC 应该只关注单一功能
- 避免在 BloC 中直接使用 BuildContext
- 使用 freezed 或 equatable 来简化状态和事件的比较
- 编写单元测试:BLoC 很容易测试,因为它是纯 Dart 代码
项目结构建议
lib/features/feature_name/bloc/feature_bloc.dartfeature_event.dartfeature_state.dartviews/feature_page.dartwidgets/feature_widget.dartrepositories/feature_repository.dartmain.dart
BLoC 架构可以帮助你构建可维护、可测试的 Flutter 应用。开始时可能会觉得有些复杂,但随着使用会越来越顺手。