【Flutter 必备插件】状态管理 flutter_bloc

flutter_bloc 是基于 BLoC(Business Logic Component)模式的 Flutter 状态管理库,它封装了 bloc package,帮助我们更清晰地组织业务逻辑与 UI 的分离。核心思想是事件驱动 和 状态响应

核心概念

  • Event(事件):用户的输入或其他外部触发,比如按钮点击。
  • State(状态):界面状态的表现,比如加载中、成功、失败。
  • Bloc(逻辑组件):接收事件 -> 处理逻辑 -> 发出新状态。

流程图如下:

UI → Bloc.add(Event) → Bloc → emit(State) → UI rebuild

实战:以登录流程为例

1. 封装数据层

class UserService {

  static Future<ApiResponse> smsLoginCode(String mobile) async {
    final response = await HttpUtil().post('/api/sms/sendLoginCode',
        data: { 'mobile': mobile,} );
    return ApiResponse.fromJson(response, null);
  }

  static Future<ApiResponse<Token>> loginCode(String mobile, String passWord) async {
    final response = await HttpUtil().post('/api/smsLogin',
        data: { 'passWord': passWord, 'userName': mobile} );
    return ApiResponse<Token>.fromJson(response, (json) => Token.fromJson(json));
  }
}

2. 封装 BLoc(逻辑层)

1.定义 Event

part of 'login_bloc.dart';

abstract class LoginEvent {}

class PhoneSmsLogin extends LoginEvent {
  PhoneSmsLogin({ required this.phone, required this.smsCode});
  final String phone;
  final String smsCode;
}

2.定义 State

part of 'login_bloc.dart';

abstract class LoginState {}

class LoginInitial extends LoginState {}

class LoginLoading extends LoginState {}

class LoginSuccess extends LoginState {}

class LoginFailure extends LoginState {}

3.实现 BLoC

part 'login_event.dart';
part 'login_state.dart';

class LoginBloc extends Bloc<LoginEvent, LoginState> {
  LoginBloc() : super(LoginInitial()) {
    on<PhoneSmsLogin>((event, emit) async {

      emit(LoginLoading());

      ApiResponse<Token> token = await UserService.loginCode(event.phone, event.smsCode);
      UserStorage.setToken(token.data!);

      emit(LoginSuccess());
    });
  }

}
  1. UI 层使用 BLoC(展示层)

main.dart

runApp(
    MultiBlocProvider(
      providers: [
        BlocProvider(create: (context) => LoginBloc()),
      ],
      child: const App()
    )
  );

登录页

@override
  Widget build(BuildContext context) {

    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        forceMaterialTransparency: true,
        toolbarHeight: 0,
      ),
      body: BlocProvider.value(
        value: context.read<LoginBloc>(),
        child: BlocConsumer<LoginBloc, LoginState>(
          builder: (context, state) {
            // if (state is LoginLoading) {
            //   return Center(child: Text("正在请求服务器"),);
            // }

            return Container(
              alignment: Alignment.center,
              margin: const EdgeInsets.only(top: 50.0),
              child: Column(
                children: [
                  _logo(),
                  _phone(),
                  _sms(),
                  _loginBtn(),
                ],
              ),
            );
          },
          listener: (context, state) {
            if (state is LoginLoading) {

            } else if (state is LoginSuccess) {
              GoRouterUtil.pop(context);
            } else if (state is LoginFailure) {

            }
          }
        ),
      ),
    );
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YueYa-Tech

你的鼓励是我坚持的源泉

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值