Javascript is required
GetX状态管理

计数器

Store

import 'package:get/get.dart';
1. 继承GetxController
2. 调用GetBuilder的builder方法
import 'package:get/get.dart';

class CalcDemo extends GetxController {
  int counter = 0;
  void increment(){
    counter++;
    update(); // GetxController通过update()更新GetBuilder
  }
}

Main

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

import 'store.dart';

class Demo1 extends StatefulWidget {
  @override
  _Demo1State createState() => _Demo1State();
}

class _Demo1State extends State<Demo1> {
  // 1. Get.put()是最常见的注入依赖的方法,它是直接注入到内存里。你可以在任何地方找到注入的对象
  final CalcDemo calcController = Get.put<CalcDemo>(CalcDemo());
  @override
  Widget build(BuildContext context) {
    // 2. GetBuilder组件
    return GetBuilder(
      init: calcController,
      builder: (controller){
        return Scaffold(
          appBar: AppBar(
            title: Text('计数器_${calcController.counter}'),
          ),
          body: Center(
            child: Text('${calcController.counter}', style: TextStyle(
                fontSize: 66
            ),),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: (){
              calcController.increment();
            },
            child: Icon(Icons.add),
          ),
        );
      },
    );
  }
}

因为controlle作用域问题,此时按钮里面的 controller会找不到,GetX强大的一点的就表现出来了,按钮和文本并不在父子组件,并且和GetBuilder不在一个作用域,但是我们依然能正确得到。

有时我们只想重新 build 需要变化的部分,遵循最小原则,那么我们改下GetBuilder的位置,只包裹 Text

# before
final CalcDemo calcController = Get.put(CalcDemo());
calcController.increment();

# now
Get.find<CalcDemo>().increment();

image-20210308213257178


生命周期

import 'package:get/get.dart';

class CalcDemo extends GetxController {
  int counter = 0;
  void increment(){
    counter++;
    update(); // GetxController通过update()更新GetBuilder
  }

  @override
  void onInit() {
    print("on init...");
    super.onInit();
  }
  @override
  void onClose() {
    print("on close...");
    super.onClose();
  }
  @override
  void onReady() {
    print("on ready...");
    super.onReady();
  }
}

开始进入页面,到离开页面

Performing hot reload...
Syncing files to device iPhone 11...
Reloaded 0 of 618 libraries in 60ms.

[GETX] GOING TO ROUTE /() => Demo3
flutter: on init...
[GETX] Instance "CalcDemo" has been created
[GETX] Instance "CalcDemo" has been initialized
flutter: on ready...
[GETX] CLOSE TO ROUTE /() => Demo3
flutter: currentRoute.isDialog false
flutter: on close...
[GETX] "CalcDemo" onDelete() called
[GETX] "CalcDemo" deleted from memory

响应式状态管理

有一个名称变量,并且希望每次你改变它时,所有使用它的小组件都会自动刷新

定义

// 方式1
var name = 'Taoya'.obs; // 会转化Rx类型

// 方式2
final name = RxString('Taoya'); // Rx{Type}

// 方式3
final name = Rx<String>('Taoya'); // Rx<Type> 指定泛型

// 延展
1. 将我们的类值转换为 obs
class RxUser {
  final name = "Camila".obs;
  final age = 18.obs;
}

2. 将整个类转换为一个可观察的类
class User {
  User({String name, int age});
  var name;
  var age;
}
//实例化时。
final user = User(name: "Camila", age: 18).obs;
转化为可观察的变量后,它的类型不再是原生类型,所以取值不能用变量本身,而是.value

响应

Obx(()=> Text(controller.name));

计算

// controller
final count1 = 0.obs;
final count2 = 0.obs;
int get sum => count1.value + count2.value;

// 视图
GetX<Controller>(
  builder: (controller) {
    print("count 1 rebuild");
    return Text('${controller.count1.value}');
  },
),
GetX<Controller>(
  builder: (controller) {
    print("count 2 rebuild");
    return Text('${controller.count2.value}');
  },
),
GetX<Controller>(
  builder: (controller) {
    print("count 3 rebuild");
    return Text('${controller.sum}');
  },
),

参考

https://github.com/jonataslaw/getx/blob/master/documentation/zh_CN/state_management.md

https://juejin.cn/post/6913917533997891591