Flutter状态管理插件mobx的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter状态管理插件mobx的使用

简介

MobX 是一个用于Dart语言的状态管理库,它简化了应用中的状态与UI之间的连接。通过透明的功能反应式编程(TFRP),MobX使得开发者可以专注于需要在UI中消费的响应式数据,而无需担心保持它们同步的问题。

以下是关于如何在Flutter项目中使用MobX进行状态管理的详细介绍和示例代码。

核心概念

Observables(可观察对象)

Observables表示应用程序的响应式状态。它可以是简单的标量或复杂的对象树。通过定义应用程序的状态为观测值树,你可以暴露一个可以被UI或其他观察者使用的响应式状态树

import 'package:mobx/mobx.dart';

part 'counter.g.dart';

class Counter = CounterBase with _$Counter;

abstract class CounterBase with Store {
  @observable
  int value = 0;

  @action
  void increment() {
    value++;
  }
}

Actions(动作)

Actions是用来改变observables的方式。与其直接改变它们,actions为这些改变添加了语义意义。例如,不是简单地执行value++,调用increment() action具有更多的含义。此外,actions还会批量处理所有的通知,并确保只有在完成之后才通知变化。

@action
void increment() {
  value++;
}

Reactions(反应)

Reactions完成了MobX的三要素:observables、actions和reactions。它们是响应式系统的观察者,在跟踪的observables发生变化时会收到通知。

  • autorun:立即运行并在任何observables变化时再次运行。
  • reaction:当fn()函数返回不同值时运行effect()
  • when:当predicate()返回true时运行effect()一次。
  • Observer:用于UI的反应,当observables变化时重建并渲染。
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';

part 'counter.g.dart';

class Counter = CounterBase with _$Counter;

abstract class CounterBase with Store {
  @observable
  int value = 0;

  @action
  void increment() {
    value++;
  }
}

class CounterExample extends StatefulWidget {
  const CounterExample({Key key}) : super(key: key);

  @override
  _CounterExampleState createState() => _CounterExampleState();
}

class _CounterExampleState extends State<CounterExample> {
  final _counter = Counter();

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('Counter'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Observer(
                  builder: (_) => Text(
                        '${_counter.value}',
                        style: const TextStyle(fontSize: 20),
                      )),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _counter.increment,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      );
}

示例项目

Counter

这是一个非常简单的计数器例子,展示了如何使用@observable@action注解来简化MobX的使用。

import 'package:mobx/mobx.dart';

part 'counter.g.dart';

class Counter = CounterBase with _$Counter;

abstract class CounterBase with Store {
  @observable
  int value = 0;

  @action
  void increment() {
    value++;
  }
}

Todos

此示例展示了MobX的一些核心特性,如ObservableComputedAction

Todo

每个Todo实体都有两个可观察属性:descriptiondone

import 'package:mobx/mobx.dart';

part 'example.g.dart';

class Todo = TodoBase with _$Todo;

abstract class TodoBase with Store {
  TodoBase(this.description);

  @observable
  String description = '';

  @observable
  bool done = false;
}

TodoList

TodoList管理Todo列表,并计算出待办事项和已完成事项的数量。

enum VisibilityFilter { all, pending, completed }

class TodoList = TodoListBase with _$TodoList;

abstract class TodoListBase with Store {
  @observable
  ObservableList<Todo> todos = ObservableList<Todo>();

  @observable
  VisibilityFilter filter = VisibilityFilter.all;

  @observable
  String currentDescription = '';

  @computed
  ObservableList<Todo> get pendingTodos =>
      ObservableList.of(todos.where((todo) => todo.done != true));

  @computed
  ObservableList<Todo> get completedTodos =>
      ObservableList.of(todos.where((todo) => todo.done == true));

  @computed
  bool get hasCompletedTodos => completedTodos.isNotEmpty;

  @computed
  bool get hasPendingTodos => pendingTodos.isNotEmpty;

  @computed
  String get itemsDescription =>
      '${pendingTodos.length} pending, ${completedTodos.length} completed';

  @computed
  ObservableList<Todo> get visibleTodos {
    switch (filter) {
      case VisibilityFilter.pending:
        return pendingTodos;
      case VisibilityFilter.completed:
        return completedTodos;
      default:
        return todos;
    }
  }

  @action
  void addTodo(String description) {
    final todo = Todo(description);
    todos.add(todo);
    currentDescription = '';
  }

  @action
  void removeTodo(Todo todo) {
    todos.removeWhere((x) => x == todo);
  }

  @action
  void changeDescription(String description) =>
      currentDescription = description;

  @action
  void changeFilter(VisibilityFilter filter) => this.filter = filter;

  @action
  void removeCompleted() {
    todos.removeWhere((todo) => todo.done);
  }

  @action
  void markAllAsCompleted() {
    for (final todo in todos) {
      todo.done = true;
    }
  }
}

通过以上内容,你应该能够理解如何在Flutter项目中使用MobX进行状态管理。希望这对你的开发有所帮助!


更多关于Flutter状态管理插件mobx的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter状态管理插件mobx的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用MobX进行状态管理的代码示例。MobX是一个强大的状态管理库,特别适合与Flutter一起使用。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加MobX和Flutter MobX的依赖:

dependencies:
  flutter:
    sdk: flutter
  mobx: ^2.0.5  # 请检查最新版本
  flutter_mobx: ^2.0.3  # 请检查最新版本

然后运行flutter pub get来安装这些依赖。

2. 创建一个Store

接下来,你需要创建一个Store类来管理状态。在这个例子中,我们将创建一个简单的计数器应用。

import 'package:mobx/mobx.dart';

part 'counter_store.g.dart';

class CounterStore = _CounterStore with _$CounterStore;

abstract class _CounterStore with Store {
  @observable
  int count = 0;

  @action
  void increment() {
    count++;
  }

  @action
  void decrement() {
    count--;
  }
}

注意,你需要运行flutter pub run build_runner build来生成counter_store.g.dart文件,这个文件包含MobX需要的代码。

3. 将Store注入到Widget中

为了使用Store,我们需要将它注入到Widget树中。这通常是通过Provider来实现的。

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

void main() {
  runApp(Provider<CounterStore>(
    create: (_) => CounterStore(),
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

4. 使用Store中的数据

现在,你可以在Widget中使用Store中的数据了。使用Observer来监听Store的变化,并更新UI。

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

class MyHomePage extends StatelessWidget {
  final CounterStore counterStore = context.read<CounterStore>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter MobX Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Observer(
              builder: (_) => Text(
                'You have pushed the button this many times:',
              ),
            ),
            Observer(
              builder: (_) => Text(
                '${counterStore.count}',
                style: Theme.of(context).textTheme.headline4,
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => counterStore.increment(),
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

5. 运行应用

现在你可以运行你的Flutter应用,并看到计数器在按下按钮时更新。

总结

这是一个简单的Flutter MobX状态管理示例。通过使用MobX,你可以轻松地管理应用的状态,并在数据变化时自动更新UI。MobX还支持更复杂的场景,比如嵌套Store、事务处理、反应式计算属性等,可以根据你的需求进行扩展。

回到顶部