Flutter Bloc / Cubit 最新详解与实战指南(2026版)

在 Flutter 状态管理方案中,Bloc(Business Logic Component)依然是企业级项目最稳定、最规范的选择之一。随着版本演进(Bloc v8+),API 已经更加简洁、类型安全更强。

本文将带你从 0 到 1 掌握:

  • Bloc & Cubit 核心原理
  • 最新 API 用法(2026)
  • 实战示例(登录 + 列表)
  • Bloc vs Cubit 对比
  • 与 GetX / Provider 区别
  • 项目最佳实践

一、什么是 Bloc?

Bloc 是一种基于 事件驱动(Event-driven)+ 单向数据流(Unidirectional Data Flow) 的状态管理方案。

核心思想:

复制代码
UI -> Event -> Bloc -> State -> UI

👉 UI 只负责发送事件

👉 Bloc 负责处理逻辑

👉 State 负责描述状态

二、Bloc vs Cubit(重点)

1️⃣ Cubit(推荐优先使用)

更轻量,没有 Event:

复制代码
UI -> Cubit -> State

适合场景:

  • 页面状态
  • 表单
  • 简单业务逻辑

示例代码:

dart 复制代码
class CounterCubit extends Cubit<int> {
  CounterCubit() : super(0);

  void increment() => emit(state + 1);
  void decrement() => emit(state - 1);
}

2️⃣ Bloc(复杂场景)

有 Event:

复制代码
UI -> Event -> Bloc -> State

适合场景:

  • 复杂业务流程
  • 多状态转换
  • 异步流复杂控制

三、最新版 Bloc 写法(重点)

Bloc v8+ 推荐使用 on 注册事件

1️⃣ 定义 Event

dart 复制代码
abstract class CounterEvent {}

class IncrementEvent extends CounterEvent {}

class DecrementEvent extends CounterEvent {}

2️⃣ 定义 State

dart 复制代码
class CounterState {
  final int count;

  CounterState(this.count);
}

3️⃣ 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));
    });

  }
}

四、UI 层使用(核心)

1️⃣ 提供 Bloc

dart 复制代码
BlocProvider(
  create: (_) => CounterCubit(),
  child: MyPage(),
)

2️⃣ 监听状态

dart 复制代码
BlocBuilder<CounterCubit, int>(
  builder: (context, count) {
    return Text('$count');
  },
)

3️⃣ 触发事件 / 方法

dart 复制代码
context.read<CounterCubit>().increment();

五、完整实战:登录流程(推荐收藏🔥)

状态设计

dart 复制代码
enum LoginStatus { initial, loading, success, error }

class LoginState {
  final LoginStatus status;
  final String? error;

  LoginState({
    this.status = LoginStatus.initial,
    this.error,
  });

  LoginState copyWith({
    LoginStatus? status,
    String? error,
  }) {
    return LoginState(
      status: status ?? this.status,
      error: error,
    );
  }
}

Cubit 实现

dart 复制代码
class LoginCubit extends Cubit<LoginState> {
  LoginCubit() : super(LoginState());

  Future<void> login(String username, String password) async {
    emit(state.copyWith(status: LoginStatus.loading));

    try {
      await Future.delayed(Duration(seconds: 2));

      if (username == "admin") {
        emit(state.copyWith(status: LoginStatus.success));
      } else {
        throw Exception("账号错误");
      }
    } catch (e) {
      emit(state.copyWith(
        status: LoginStatus.error,
        error: e.toString(),
      ));
    }
  }
}

UI 写法

dart 复制代码
BlocConsumer<LoginCubit, LoginState>(
  listener: (context, state) {
    if (state.status == LoginStatus.success) {
      ScaffoldMessenger.of(context)
          .showSnackBar(SnackBar(content: Text("登录成功")));
    }
  },
  builder: (context, state) {
    if (state.status == LoginStatus.loading) {
      return CircularProgressIndicator();
    }

    return ElevatedButton(
      onPressed: () {
        context.read<LoginCubit>().login("admin", "123");
      },
      child: Text("登录"),
    );
  },
);

六、Bloc 常用组件总结

组件 作用
BlocProvider 提供 Bloc
BlocBuilder 构建 UI
BlocListener 监听副作用
BlocConsumer Builder + Listener
RepositoryProvider 提供数据层

七、Bloc 最佳实践(非常重要)

✅ 1. 分层结构

推荐结构:

复制代码
lib/
 ├── data/          // 数据层
 ├── repository/    // 仓库层
 ├── cubit / bloc/  // 状态管理层
 ├── view/          // 视图层

✅ 2. 状态不可变(immutable)

推荐使用:

  • freezed
  • equatable
dart 复制代码
class CounterState extends Equatable {
  final int count;

  const CounterState(this.count);

  @override
  List<Object> get props => [count];
}

✅ 3. 避免在 UI 写逻辑

❌ 错误写法:

dart 复制代码
onPressed: () {
  if (xxx) ... // 逻辑直接写在UI中
}

✅ 正确写法:

dart 复制代码
onPressed: () {
  cubit.doSomething(); // 逻辑封装在Cubit/Bloc中
}

✅ 4. 使用 BlocObserver 调试

dart 复制代码
class MyObserver extends BlocObserver {
  @override
  void onChange(BlocBase bloc, Change change) {
    print(change);
    super.onChange(bloc, change);
  }
}

八、Bloc vs GetX vs Provider

特性 Bloc GetX Provider
学习成本 高 低 中
规范性 ⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐
可维护性 ⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐
企业级 ✅ ⚠️ ✅
响应式 中 强 中

👉 总结:

  • 小项目 → GetX
  • 中项目 → Provider / Cubit
  • 大项目 → Bloc(推荐)

九、Bloc 适合什么项目?

✅ 推荐使用场景:

  • 中大型 Flutter 项目
  • 多人协作
  • 复杂业务(支付、IM、视频流)
  • 需要高可维护性

十、总结

一句话总结:

👉 Cubit = 简化版 Bloc(80% 场景够用)

👉 Bloc = 复杂业务的终极方案

🎯 最终建议(2026)

  • ✔ 优先用 Cubit
  • ✔ 复杂逻辑再用 Bloc
  • ✔ 配合 freezed + repository 才是完整体
相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
茶底世界之下3 天前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas