共计 4398 个字符,预计需要花费 11 分钟才能阅读完成。
文 / Paul Halliday, developer.school 创始人
家喻户晓,状态治理是每个软件我的项目都须要继续迭代更新的方向。它并不是一个「一次性」的工作,
而须要一直确保你遵循的最佳实际可能让你的工程保持良好的可维护性。
要在 Flutter 中高效地应用 MobX,须要遵循以下准则:
- 咱们能拜访任意状态中的可察看对象(即在咱们利用运行过程中发生变化的变量)。
- 咱们能够在 View 中展现这些状态,并响应 Action 用意。
- 咱们能够批改状态,从而更新可察看对象以及相应的 View。
那么它的劣势在哪呢?答案是,通过 MobX 实现这所有将会变得超级简略!codegen 工具能够帮咱们实现绝大部分模版化的工作。
初始化我的项目
让咱们从创立一个全新的 Flutter 工程开始吧:
# New Flutter project | |
$ flutter create f_mobx && cd f_mobx | |
# Open in VS Code | |
$ code . |
下一步,咱们得在 pubspec.yaml
中拉取一些依赖 (dependencies
与 dev_dependencies
):
dependencies: | |
flutter: | |
sdk: flutter | |
mobx: | |
flutter_mobx: | |
dev_dependencies: | |
flutter_test: | |
sdk: flutter | |
build_runner: ^1.3.1 | |
mobx_codegen: |
之后咱们能够在 main.dart
中创立一个全新的 MaterialApp
以搁置咱们的 CounterPage
。
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
创立好了咱们的计数器。当初,让咱们来看看代码,逐行进行解释:
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--;} | |
} |
- 咱们导入了
mobx.dart
,这样就能够拜访 Store 以及其余性能了。 - 接下来,咱们应用了
part
语法组合此类的主动生成的局部。咱们临时还没应用到生成器,然而别放心,咱们将会在下一个局部进行这个操作。 - 接下来,咱们将裸露
Counter
类,该类将与生成的与 MobX 绑定的_$Counter
类一起应用。 - 最初,咱们应用 Store 类创立一个
_Counter
,并定一个@observable
属性和@actions
以确定 Store 能够与之交互的区域。
MobX 曾经帮咱们做了绝大部分繁琐的事件,所以咱们不须要关怀底层是如何实现的。
当初咱们曾经有了 Counter
类,让咱们在终端的该工程目录下通过上面的命令运行 build_runner
和 mobx_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, | |
), | |
], | |
) | |
], | |
), | |
)); | |
} | |
} |
让咱们深入研究一下:
- 咱们导入了
flutter_mobx
以及咱们的 Counter store,所以之后咱们能够用到他们。 - 接下来,咱们初始化了
Counter
,并将其命名为counter
,之后咱们就能够轻松监听这个可察看对象的值,或是收回actions:final Counter counter = Counter()
; - 咱们应用 Observer 监听
counter.value
的值。 - 咱们将 onPressed 事件绑定到
counter.increment
和counter.decrement
,它们会将action
发送到 Store。
下面这些代码联合起来就实现了咱们小型的计数器利用!
总结
心愿这篇 MobX 的介绍可能帮到你。我目前仍在继续摸索 Flutter 状态治理的最佳实际,所以我也十分期待未来能对该系列进一步的更新。
原文:https://developer.school/flutter-state-management-with-mobx/
注:文章 & 视频本地化和公布已取得作者自己受权
致谢
- 本文作者:Paul Halliday
- 中文字幕翻译: Alex、鑫磊
- 文章翻译:加康、鑫磊
- 头图:Lynn