Flutter 状态管理- 使用 MobX

文 / Paul Halliday, developer.school 创始人shell

众所周知,状态管理是每一个软件项目都须要持续迭代更新的方向。它并非一个「一次性」的工做,
而须要不断确保你遵循的最佳实践可以让你的工程保持良好的可维护性。app

要在 Flutter 中高效地使用 MobX ,须要遵循如下原则:less

  1. 咱们能访问任意状态中的可观察对象(即在咱们应用运行过程当中发生变化的变量)。
  2. 咱们能够在 View 中展现这些状态,并响应 Action 意图。
  3. 咱们能够修改状态,从而更新可观察对象以及相应的 View。

那么它的优点在哪呢?答案是,经过 MobX 完成这一切将会变得超级简单!codegen 工具能够帮咱们完成绝大部分模版化的工做。ide

初始化项目

让咱们从建立一个全新的 Flutter 工程开始吧:工具

# New Flutter project
$ flutter create f_mobx && cd f_mobx
 
# Open in VS Code
$ code .

下一步,咱们得在 pubspec.yaml 中拉取一些依赖 (dependenciesdev_dependencies):ui

dependencies: 
 flutter:
    sdk: flutter
 
  mobx:
  flutter_mobx:
 
dev_dependencies:
  flutter_test:
    sdk: flutter
 
  build_runner: ^1.3.1
  mobx_codegen:

以后咱们能够在 main.dart 中建立一个全新的 MaterialApp 以放置咱们的 CounterPagethis

import 'package:f_mobx/pages/counter_page.dart';
import 'package:flutter/material.dart';
 
void main() => runApp(MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: CounterPage(),
    );
  }
}

下一步,咱们须要在 lib/pages/counter_page.dart 中建立 CounterPage,并完成用户界面的构建。其中包括了一个增长按钮和一个减小按钮。翻译

import 'package:flutter/material.dart';
 
class CounterPage extends StatelessWidget {
 
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: AppBar(
          title: Text('Flutter and MobX'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'Counter',
                style: TextStyle(fontSize: 30.0),
              ),
              Text(
                '0', 
                style: TextStyle(fontSize: 42.0),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  FlatButton.icon(
                    icon: Icon(Icons.add),
                    label: Text('Add'),
                    onPressed: () {},
                  ),
                  FlatButton.icon(
                    icon: Icon(Icons.remove),
                    label: Text('Remove'),
                    onPressed: () {},
                    ),
                  ),
                ],
              )
            ],
          ),
        ));
  }
}

建立计数器的状态

太棒了!咱们如今已经在 lib/store/counter/counter.dart 建立好了咱们的计数器。如今,让咱们来看看代码,逐行进行解释:code

import 'package:mobx/mobx.dart';
 
// This is our generated file (we'll see this soon!)
part 'counter.g.dart';
 
// We expose this to be used throughout our project
class Counter = _Counter with _$Counter;
 
// Our store class
abstract class _Counter with Store {
  @observable
  int value = 1;
 
  @action
  void increment() {
    value++;
  }
 
  @action
  void decrement() {
    value--;
  }
}
  1. 咱们导入了 mobx.dart,这样就能够访问 Store 以及其余功能了。
  2. 接下来,咱们使用了 part 语法组合此类的自动生成的部分。咱们暂时还没使用到生成器,可是别担忧,咱们将会在下一个部分进行这个操做。
  3. 接下来,咱们将暴露 Counter 类,该类将与生成的与 MobX 绑定的 _$Counter 类一块儿使用。
  4. 最后,咱们使用 Store 类建立一个 _Counter,并定一个 @observable 属性和 @actions 以肯定 Store 能够与之交互的区域。

MobX 已经帮咱们作了绝大部分繁琐的事情,因此咱们不须要关心底层是如何实现的。视频

如今咱们已经有了 Counter 类,让咱们在终端的该工程目录下经过下面的命令运行 build_runnermobx_codegen

$ flutter packages pub run build_runner watch

咱们如今应该能够看到生成的 counter.g.dart 文件。它看上去相似下面这样:

part of 'counter.dart';
mixin _$Counter on _Counter, Store {
  final _$valueAtom = Atom(name: '_Counter.value');
 
  @override
  int get value {
    _$valueAtom.reportObserved();
    return super.value;
  }
 
  @override
  set value(int value) {
    _$valueAtom.context.checkIfStateModificationsAreAllowed(_$valueAtom);
    super.value = value;
    _$valueAtom.reportChanged();
  }
 
  final _$_CounterActionController = ActionController(name: '_Counter');
 
  @override
  void increment() {
    final _$actionInfo = _$_CounterActionController.startAction();
    try {
      return super.increment();
    } finally {
      _$_CounterActionController.endAction(_$actionInfo);
    }
  }
 
  @override
  void decrement() {
    final _$actionInfo = _$_CounterActionController.startAction();
    try {
      return super.decrement();
    } finally {
      _$_CounterActionController.endAction(_$actionInfo);
    }
  }
}

这些东西,咱们都不须要本身来实现!是否是很棒呀?

与 Store 进行绑定

接下来,咱们须要让 counter_page.dart 绑定到 Counter store。让咱们再次看看它长什么样,而后进行深刻探索:

import 'package:flut_mobx/store/counter/counter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
 
class CounterPage extends StatelessWidget {
  final Counter counter = Counter();
 
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: AppBar(
          title: Text('Flutter and MobX'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'Counter',
                style: TextStyle(fontSize: 30.0),
              ),
              Observer(
                builder: (_) =>
                    Text('${counter.value}', style: TextStyle(fontSize: 42.0)),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  FlatButton.icon(
                    icon: Icon(Icons.add),
                    label: Text('Add'),
                    onPressed: counter.increment,
                  ),
                  FlatButton.icon(
                    icon: Icon(Icons.remove),
                    label: Text('Remove'),
                    onPressed: counter.decrement,
                  ),
                ],
              )
            ],
          ),
        ));
  }
}

让咱们深刻研究一下:

  1. 咱们导入了 flutter_mobx 以及咱们的 Counter store,因此以后咱们能够用到他们。
  2. 接下来,咱们初始化了 Counter,并将其命名为 counter,以后咱们就能够轻松监听这个可观察对象的值,或是发出 actions:final Counter counter = Counter();
  3. 咱们使用 Observer 监听 counter.value 的值。
  4. 咱们将 onPressed 事件绑定到 counter.incrementcounter.decrement,它们会将 action 发送到 Store。

上面这些代码结合起来就完成了咱们小型的计数器应用!

总结

但愿这篇 MobX 的介绍可以帮到你。我目前仍在持续探索 Flutter 状态管理的最佳实践,因此我也很是期待未来能对该系列进一步的更新。

原文: https://developer.school/flutter-state-management-with-mobx/
注:文章 & 视频本地化和发布已得到做者本人受权

致谢

  • 本文做者:Paul Halliday
  • 中文字幕翻译: Alex、鑫磊
  • 文章翻译:加康、鑫磊
  • 头图:Lynn
相关文章
相关标签/搜索