1. Cubit-簡單狀態管理
dependencies:
flutter_bloc: ^8.1.0
hydrated_bloc: ^9.1.0
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void decrement() => emit(state - 1);
void reset() => emit(0);
}
2. Bloc-事件驅動
// Events
sealed class AuthEvent {}
class AuthLoginRequested extends AuthEvent {
final String email;
final String password;
AuthLoginRequested({required this.email, required this.password});
}
class AuthLogoutRequested extends AuthEvent {}
// States
sealed class AuthState {}
class AuthInitial extends AuthState {}
class AuthLoading extends AuthState {}
class AuthAuthenticated extends AuthState {
final User user;
AuthAuthenticated(this.user);
}
class AuthError extends AuthState {
final String message;
AuthError(this.message);
}
// Bloc
class AuthBloc extends Bloc<AuthEvent, AuthState> {
final AuthRepository _authRepository;
AuthBloc(this._authRepository) : super(AuthInitial()) {
on<AuthLoginRequested>(_onLogin);
on<AuthLogoutRequested>(_onLogout);
}
Future<void> _onLogin(AuthLoginRequested event, Emitter<AuthState> emit) async {
emit(AuthLoading());
try {
final user = await _authRepository.login(event.email, event.password);
emit(AuthAuthenticated(user));
} catch (e) {
emit(AuthError(e.toString()));
}
}
Future<void> _onLogout(AuthLogoutRequested event, Emitter<AuthState> emit) async {
await _authRepository.logout();
emit(AuthInitial());
}
}
3. BlocProvider、BlocBuilder、BlocListener
// Provide
MultiBlocProvider(
providers: [
BlocProvider(create: (_) => AuthBloc(authRepo)),
BlocProvider(create: (_) => ThemeBloc()),
],
child: const MyApp(),
);
// Build
BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) => switch (state) {
AuthLoading() => const CircularProgressIndicator(),
AuthAuthenticated(:final user) => Text('Welcome ${user.name}'),
AuthError(:final message) => Text(message),
_ => const LoginForm(),
},
);
// Listen — side effects
BlocListener<AuthBloc, AuthState>(
listener: (context, state) {
if (state is AuthError) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(state.message)));
}
},
child: const LoginForm(),
);
// BlocConsumer = Builder + Listener
BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {
if (state is AuthAuthenticated) {
context.go('/home');
}
},
builder: (context, state) {
return ElevatedButton(
onPressed: state is AuthLoading ? null : () {
context.read<AuthBloc>().add(AuthLoginRequested(email: email, password: password));
},
child: state is AuthLoading ? const CircularProgressIndicator() : const Text('Login'),
);
},
);
4. 水合塊-持久狀態
class ThemeBloc extends HydratedCubit<ThemeMode> {
ThemeBloc() : super(ThemeMode.system);
void toggle() => emit(state == ThemeMode.dark ? ThemeMode.light : ThemeMode.dark);
@override
ThemeMode fromJson(Map<String, dynamic> json) =>
ThemeMode.values[json['mode'] as int];
@override
Map<String, dynamic> toJson(ThemeMode state) => {'mode': state.index};
}
下一篇: 表單、驗證和主題。