Flutter 入门与实战(八十三):GetX 状态管理怎么用,看这一篇就够了!

发布时间:2021年10月04日 阅读:10 次

GetX 从前到后我们也写了10多篇了,本篇对 GetX 状态管理部分的用法做一下总结,在实际开发过程中可以根据自身需要针对性的选择具体的用法。

简单状态管理 GetBuilder

GetBuilder 最大的好处是简单易用,尤其是对于从 Proivider 迁移过来的时候,代码改动量是很小的。编写的过程如下:

  • 编写 Controller 代码,在 VSCode 里 安装了 GetX Snippets 插件后可以使用 get controller快速插入Controller 代码模板。

  • 将使用到状态对象的 Widget 使用 GetBuilder 包裹起来,如下所示:

Widget build(BuildContext context) {   return GetBuilder<CounterController>(     // 初始化 Controller     init: Controller(),     // 在 builder里返回具体的 Widget     builder: (controller) => XXXWidget(),   ); } 复制代码

  • 在引用状态对象的时候,直接引用builder参数中的controller即可。

  • 在完成更新状态对象的时候,手动调用一下 update 方法。注意,如果想定向更新,可以在 update 方法里插入一个 数组,这样只有GetBuilder 指定的id 在该数据组中才会更新。具体示例可以参考:Flutter 入门与实战(七十五):模拟红绿灯来看GetX的定向刷新。

  • 如果一个 Controller 需要被多个不在同一组件树的Widget 使用,可以在 Controller 中定义一个静态属性使用 Get.find()获取状态对象或直接使用Get<T>.find()。之所以能够这么用是因为在 GetBuilder 初始化的时候将当前的状态对象放入到容器中了,具体大家可以看 GetBuilder 的源码实现。

static CounterController get to => Get.find(); 复制代码

实际上 GetBuilder是一个 StatefulWidget 的子类,在 update 被调用的时候,会调用builder参数的方法来刷新对应的组件。

GetxController具有自己生命周期,我们可以在不同的生命周期处理不同的业务,从而无需再引入 StatefulWidget 来管理生命周期了。可以参考:Flutter 入门与实战(七十四):GetxController 的生命周期详解。

响应式状态管理GetX

GetBuilder 相比,响应式状态管理相当于实现了状态对象的绑定,只要状态对象发生了改变,依赖状态对象的组件会自动刷新,而不需要手动调用 upade 刷新,这会使得我们的代码更为简洁。GetX 实现响应的方式是定义了一个 Rx<T>的扩展(也可以使用 T.obs),当 Rx<T>对象的值变化的时候会通知 GetX<Controller>刷新,从而调用 GetX<Controller>的 builder 参数重新构建组件。具体示例可以看参考:Flutter 入门与实战(七十六):GetX 响应式状态管理简介。

还有一种更简洁的用法,那就是 Obx,但是这种方式有个缺陷那就是状态对象 GetxController的生命周期函数不会被调用,更适用于简单的组件,性能当然也会更高些。

class CounterController extends GetxController {   var _counter = 0.obs;   static CounterController get to => Get.find();   get counter => _counter.value;   void increment() {     _counter.value++;   } } class CounterPage extends StatelessWidget {   CounterPage({Key? key}) : super(key: key);   final CounterController controller = CounterController();   @override   Widget build(BuildContext context) {     return Scaffold(       appBar: AppBar(         title: Text('GetX计数器'),       ),       body: Center(         child: Obx(() => Text('${controller.counter}')),       ),       floatingActionButton: FloatingActionButton(         child: Icon(Icons.add),         onPressed: () {           controller.increment();         },       ),     );   } } 复制代码

混入页面状态StateMixin

使用 StateMixin 最大的好处是让我们的页面结构更优雅,当状态改变的时候调用 change 方法通知界面刷新,并且携带了一个状态。而这个状态可以自动切换不同状态对应的组件,从而避免了我们自己写一大堆的if...elseswitch 语句,组件构建的需要使用 controller.obx 包裹,并且页面需要继承GetView<PersonalMixinController>,代码如下所示,具体可以参考:Flutter 入门与实战(八十):使用GetX构建更优雅的页面结构。

class PersonalHomePageMixin extends GetView<PersonalMixinController> {   PersonalHomePageMixin({Key? key}) : super(key: key);   @override   Widget build(BuildContext context) {     return controller.obx(       (personalEntity) => _PersonalHomePage(personalProfile: personalEntity!),       onLoading: Center(         child: CircularProgressIndicator(),       ),       onError: (error) => Center(         child: Text(error!),       ),       onEmpty: Center(         child: Text('暂无数据'),       ),     );   } } 复制代码

四种方式的比较

官方对于这四种方式(Obx 也算一种)给出了优劣说明:

  • GetBuilder 消耗的内存最小,性能最优,当然代码可维护性来说就会牺牲一点,毕竟需要手动调用 update

  • Obx 的性能次之,优势是可以同时监听多个 Controller 的状态对象变化。缺点是 Controller 没有生命周期函数,而且 Controller 需要在 Obx 之外先初始化(这个倒问题不大,可以通过容器解决)。

  • GetX 更贴近实际项目一些,通过响应式的状态管理使得代码的可维护性更高。当然性能上会有些许损失。

  • StateMixin 更像是一个粘合剂,将页面的数据状态和对象粘合起来,然后简化我们构建不同状态页面的代码结构。性能上是最低的,当然这个性能差别在很多时候是体现不出来的。

至于具体怎么选择,看项目实际需要吧。

总结

本篇对 GetX 的几种状态管理用法进行了对比总结,可以看到,在状态管理方式上,GetX 提供了多样化的选择,好处是我们可以根据自己的需要自由选择。当然缺陷也是有的,多样化之后意味着同一个工程可能出现多种方式,这对代码结构的统一上不太方便。因此,实际开发中最好是约定好使用其中的1-2种方式。关于 GetX,网上的评价大多数是好评,在 pub 上的流行度也达到了99%,GitHub上目前超过了4.6k 的 star,整体来说用于生产是没问题的。当然,它也有一定的缺陷,下面一篇我们会结合一篇国外的文章客观地看一下 GetX 的缺陷。


作者:岛上码农
链接:https://juejin.cn/post/7012766280394489893


Tag:代码管理 flutter
相关文章

发表评论: