什么是 GetX?

一个简略、高效、强大的办理状况、路由办理库

学习方针

  • 掌握运用GetX办理状况
  • 了解基础GetX状况办理的原理

GetX状况办理的优势

  1. 精确烘托,只会烘托依靠状况改变的组件而不会悉数组件烘托一遍
  2. 安全性高,当程序出现错误时,不会由于重复更改状况导致崩溃
  3. 有个GetX永远不需求声明状况组件, 忘记StatefulWidget组件
  4. 完成MVC架构,将事务逻辑写到控制器中,视图层专注于烘托
  5. 内置了防抖/节省、初次履行等功用
  6. 自动毁掉控制器,无需用户手动毁掉

用法

1.1声明呼应式状况

有三种声明方法,运用哪一种都能够 推荐第三种

1.1.1 运用声明,结合Rx{Type}

final name = RxString(''); // 每种内置的类型都有对应的类
final isLogged = RxBool(false);
final count = RxInt(0);
final balance = RxDouble(0.0);
final items = RxList<String>([]);
final myMap = RxMap<String, int>({});

1.1.2 泛型声明 Rx

final name = Rx<String>(''); 
final isLogged = Rx<Bool>(false);
final count = Rx<Int>(0);
final balance = Rx<Double>(0.0);
final number = Rx<Num>(0);
final items = Rx<List<String>>([]);
final myMap = Rx<Map<String, int>>({});
// 自定义类 声明办法
final user = Rx<User>();

1.1.3以.obs作为值(推荐运用)

final name = ''.obs;
final isLogged = false.obs;
final count = 0.obs;
final balance = 0.0.obs;
final number = 0.obs;
final items = <String>[].obs;
final myMap = <String, int>{}.obs;
// 自定义类 声明办法
final user = User().obs;

2.1 运用呼应状况到视图中

有两种办法运用状况:

  1. 根据Obx收集依靠状况
  2. 根据GetX<Controller>获取对应的控制器类型

2.1.1根据Obx收集依靠状况

十分简略,咱们只需求运用静态类即可到达动态更新作用。

  1. 创建一个 Controller
// HomeController 能够写到一个专门办理控制器的文件中,这样便利保护
// 就像 React 需求把 Hook 独自提取一个文件相同
class HomeController extends GetxController {
  var count = 0.obs;
  increment() => count++;
}
  1. 导入创建的 Controller 并运用它
class Home extends StatelessWidget {
  const Home({super.key});
  @override
  Widget build(BuildContext context) {
    // 寻觅Controller
  	HomeController c = Get.find<HomeController>();
    return Obx(
      () => Scaffold(
        body: ElevatedButton(
          // 经过`c.count.value`运用状况,也能够不运用.value,.value可选的
          child: const Text("${c.count}"),
          onPressed: () => c.count++, // 改变状况,
        ),
      ),
    );
  }
}

2.1.2 根据GetX<Controller>获取对应的控制器类型

这种做法需求三个过程

  1. 声明一个控制器
// HomeController 能够写到一个专门办理控制器的文件中,这样便利保护
class HomeController extends GetxController {
  var count = 0.obs;
  increment() => count++;
}
  1. GetMaterialApp类中初始化时导入对应的控制器
// main.dart
void main() {
  runApp(GetMaterialApp(
    // 假如不写这一步那么GetX将无法找到HomeController控制器
    initialBinding: InitBinding(),
    home: const Home(),
  ));
}
class InitBinding implements Bindings {
  @override
  void dependencies() {
    Get.put(HomeController());
  }
}
  1. 在对应组件或页面中运用GetX<Controller>完成数据的呼应
class Home extends StatelessWidget {
  const Home({super.key});
  @override
  Widget build(BuildContext context) {
    // 这样就能够正常运用了
    return Obx<HomeController>( 
      builder: (c) => Scaffold(
        body: ElevatedButton(
          child: const Text(c.count.value),
          onPressed: () => c.count++,
        ),
      ),
    );
  }
}

3.1 监听状况更新的工具函数

var count = 0.obs;
// 每当 count 发生改变的时分就会触发回调函数履行
ever(count, (newCount) => print("这是count的值: $newCount"));
// 只有初次更新时才会触发
once(count, (newCount) => print("这是count的值: $newCount"));
/// 类似于防抖功用频繁触发不会每次更新,只会停止更新count后的 1秒才履行(这儿设置成了1秒)
debounce(count, (newCount) => print("这是count的值: $newCount"), time: Duration(seconds: 1));
/// 类似于节省功用 频繁更新值每秒钟只触发一次 (由于这儿设置成了1秒)
interval(count, (newCount) => print("这是count的值: $newCount"), time: Duration(seconds: 1));

GetX状况办理的疑问

1.1 哪些地方能够运用.obs

  • 能够直接在类中赋值运用
class RxUser {
  final name = "Camila".obs; 
  final age = 18.obs;
}
  • 直接将整个类都变成可调查目标
class User {
  User({String name, int age});
  var name;
  var age;
}
final user = User(name: "Camila", age: 18).obs;

1.1.2 一定要运用xxx.value获取值吗?

这个并没有强制要求运用xxx.value获取值,能够直接运用xxx这能让代码看起来愈加简洁

1.2 可调查目标是类怎么更新?

  • 两种方法能够更新,运用其中一种即可
class User() {
  User({this.name = '', this.age = 0});
  String name;
  int age;
}
final user = User().obs;
// 第一种方法
user.update( (user) {
	user.name = 'Jonny';
	user.age = 18;
});
// 第二种方法
user(User(name: 'Joo', age: 35));
// 运用方法
Obx(()=> Text("名字 ${user.value.name}: 年龄: ${user.value.age}"))
// 能够不需求带.value拜访,需求将user履行
user().name;

GetX状况办理的一些原理

1.1.1.obs原理是什么?

var name = "dart".obs

一、Flutter必学的Getx状态管理库

  • 源码仅仅经过StringExtensionString扩展了一个get特点拜访器
  • 原理还是经过RxString做绑定

tips: 假如想查看源码的话能够经过 control键 + 左击.obs就能够进入源码里面了

1.2 Obx的基本原理是什么?

  • 简而言之,Obx其实帮咱们包裹了一层有状况组件
var build = () => Text(name.value)
Obx(build);

一、Flutter必学的Getx状态管理库

承继了一个抽象ObxWidget类,将传递进来的build办法给了ObxWidget,还得看看ObxWidget做了什么

一、Flutter必学的Getx状态管理库

ObxWidget承继了有状况组件,而且build函数让Obx类完成了

一、Flutter必学的Getx状态管理库

_ObxWidget主要做了两件工作

  1. 初始化的时分监听依靠收集,毁掉时清空依靠并封闭监听。这是Obx的核心
  2. Obx完成的build函数传递给了RxInterface.notifyChildren履行

一、Flutter必学的Getx状态管理库

NotifyManager是一个混入,主要功用

  • subject特点用于传递更新告诉
  • _subscriptions特点用于存储RxNotifier实例的订阅列表
  • canUpdate办法检查是否有任何订阅者
  • addListener用于将订阅者添加到订阅列表中,当 RxNotifier 实例的值发生改变时,它将经过 subject 发出告诉,并告诉一切订阅者
  • listen办法监听subject改变并在改变时履行回调函数
  • close封闭一切订阅和开释内存等