Library Reactive Model Boilerplate Scalable Best For
ChangeNotifier Observer Low Low Small apps
Provider Inherited + Notifier Low Medium Simple DI
Riverpod Declarative Provider Medium High Production apps
Bloc (Cubit) Stream-based state machine Medium Very High Large teams
GetX Rx observable Very Low Medium Rapid dev
MobX Observable graph Medium High Reactive UIs

1️⃣ ChangeNotifier

需要安装 provider: ^6.0.0
创建一个类继承自ChangeNotifier,添加方法,数据变更时,使用notifyListeners()函数。UI Widget侧则需要Consumer类的builder函数来检测数据变化和UI更新。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => Counter(),
      child: const MyApp(),
    ),
  );
}

class Counter extends ChangeNotifier {
  int count = 0;
  void increment() {
    count++;
    notifyListeners();
  }
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Consumer<Counter>(
            builder: (_, counter, __) => Text('${counter.count}'),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () =>
              context.read<Counter>().increment(),
        ),
      ),
    );
  }
}

2️⃣ Riverpod

需要安装 flutter_riverpod: ^2.0.0
需要创建一个StateProvider,使用的时候需要通过WidgetRef来引入ref.watch变量的观测,然后ref.read即可。

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = StateProvider<int>((ref) => 0);

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);

    return MaterialApp(
      home: Scaffold(
        body: Center(child: Text('$count')),
        floatingActionButton: FloatingActionButton(
          onPressed: () =>
              ref.read(counterProvider.notifier).state++,
        ),
      ),
    );
  }
}

3️⃣ Bloc (Cubit version – simplest)

需要安装 flutter_bloc: ^8.0.0

  • a.开始:需要使用BlocProvider包裹主MaterialApp的UI,并且传入一个可观测的状态类
  • b.变更:在可观测的状态类里,当数据发生变更时,则需要通过emit()函数
  • c.使用:使用BlocBuilder的builder参数构建UI,并绑定变量到UI上
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

void main() {
  runApp(
    BlocProvider(
      create: (_) => CounterCubit(),
      child: const MyApp(),
    ),
  );
}

class CounterCubit extends Cubit<int> {
  CounterCubit() : super(0);
  void increment() => emit(state + 1);
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: BlocBuilder<CounterCubit, int>(
            builder: (_, count) => Text('$count'),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () =>
              context.read<CounterCubit>().increment(),
        ),
      ),
    );
  }
}

4️⃣ GetX

需要安装get: ^4.6.0

  • 对一个Data Model类,必须继承自GetxController
  • 使用时,必须然后通过Get.put()函数获取到实例后,便可以与UI绑定
  • 注意:一个值需要通过obs转换后才是真正的值,否则是wrapper value
import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(const MyApp());
}

class CounterController extends GetxController {
  var count = 0.obs;
  void increment() => count++;
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    final controller = Get.put(CounterController());

    return GetMaterialApp(
      home: Scaffold(
        body: Center(
          child: Obx(() => Text('${controller.count}')),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: controller.increment,
        ),
      ),
    );
  }
}

5️⃣ MobX

需要安装mobx: ^2.0.0,然后运行build_runner required

import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';

part 'counter.g.dart';

class Counter = _Counter with _$Counter;

abstract class _Counter with Store {
  
  int count = 0;

  
  void increment() => count++;
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final counter = Counter();

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Observer(
            builder: (_) => Text('${counter.count}'),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: counter.increment,
        ),
      ),
    );
  }
}
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐