什么是 GetX?
一个简略、高效、强大的办理状况、路由办理库
学习方针
- 掌握运用
GetX
办理状况 - 了解基础
GetX
状况办理的原理
GetX状况办理的优势
- 精确烘托,只会烘托依靠状况改变的组件而不会悉数组件烘托一遍
- 安全性高,当程序出现错误时,不会由于重复更改状况导致崩溃
-
有个
GetX
永远不需求声明状况组件, 忘记StatefulWidget
组件 -
完成
MVC
架构,将事务逻辑写到控制器中,视图层专注于烘托 - 内置了防抖/节省、初次履行等功用
- 自动毁掉控制器,无需用户手动毁掉
用法
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 运用呼应状况到视图中
有两种办法运用状况:
- 根据
Obx
收集依靠状况 - 根据
GetX<Controller>
获取对应的控制器类型
2.1.1根据Obx收集依靠状况
十分简略,咱们只需求运用静态类即可到达动态更新作用。
- 创建一个 Controller
// HomeController 能够写到一个专门办理控制器的文件中,这样便利保护
// 就像 React 需求把 Hook 独自提取一个文件相同
class HomeController extends GetxController {
var count = 0.obs;
increment() => count++;
}
- 导入创建的 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>
获取对应的控制器类型
这种做法需求三个过程
- 声明一个控制器
// HomeController 能够写到一个专门办理控制器的文件中,这样便利保护
class HomeController extends GetxController {
var count = 0.obs;
increment() => count++;
}
- 在
GetMaterialApp
类中初始化时导入对应的控制器
// main.dart
void main() {
runApp(GetMaterialApp(
// 假如不写这一步那么GetX将无法找到HomeController控制器
initialBinding: InitBinding(),
home: const Home(),
));
}
class InitBinding implements Bindings {
@override
void dependencies() {
Get.put(HomeController());
}
}
- 在对应组件或页面中运用
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
- 源码仅仅经过
StringExtension
向String
中扩展了一个get
特点拜访器 - 原理还是经过
RxString
做绑定
tips: 假如想查看源码的话能够经过 control
键 + 左击.obs
就能够进入源码里面了
1.2 Obx
的基本原理是什么?
- 简而言之,Obx其实帮咱们包裹了一层有状况组件
var build = () => Text(name.value)
Obx(build);
承继了一个抽象ObxWidget
类,将传递进来的build
办法给了ObxWidget
,还得看看ObxWidget
做了什么
ObxWidget
承继了有状况组件,而且build
函数让Obx
类完成了
_ObxWidget
主要做了两件工作
- 初始化的时分监听依靠收集,毁掉时清空依靠并封闭监听。这是
Obx
的核心 - 将
Obx
完成的build
函数传递给了RxInterface.notifyChildren
履行
NotifyManager
是一个混入,主要功用
- subject特点用于传递更新告诉
-
_subscriptions
特点用于存储RxNotifier
实例的订阅列表 -
canUpdate
办法检查是否有任何订阅者 -
addListener
用于将订阅者添加到订阅列表中,当 RxNotifier 实例的值发生改变时,它将经过 subject 发出告诉,并告诉一切订阅者 -
listen
办法监听subject
改变并在改变时履行回调函数 -
close
封闭一切订阅和开释内存等