GetX 全功能实战指南:状态管理、路由与依赖注入一体化方案
2026/9/23 18:26:01 网站建设 项目流程
  • 前端

【免费下载链接】getx

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.

项目地址:https://gitcode.com/gh_mirrors/ge/getx
点击查看免费下载

GetX 是 Flutter 生态中一个轻量而强大的微框架,将高性能状态管理、智能依赖注入与便捷路由管理整合在同一个包中,并支持免 context 操作 snackbar、dialog、bottomSheet 与国际化、主题切换等实用能力。本文以本仓库 README.zh-cn.md 为骨架,结合仓库源码与示例工程,系统讲解从安装、26 行计数器示例到三大核心功能、GetConnect 网络层、GetPage 中间件与高级 API 的完整用法,读完后你可以直接在自己的 Flutter 项目中落地一套「界面、逻辑、依赖、路由完全解耦」的开发范式。

关于 GetX:三大基本原则

GetX 的定位是 Flutter 上的轻量且强大的多端解决方案,官方在 README 中明确了三个基本原则:

  • 性能:专注于性能与最小资源消耗。由于整个框架由多个独立模块组成(见 lib/get.dart 的 export 结构),如果你只用状态管理,则只有状态管理模块被编译进产物,未使用的模块不会进入你的代码。
  • 效率:语法极其简捷,同时保持高性能,可显著缩短开发时长。
  • 结构:将界面、逻辑、依赖和路由完全解耦,使代码更易维护。

从源码结构看,lib/get.dart 将功能拆分为get_coreget_instanceget_navigationget_rxget_state_managerget_utilsget_connectget_animations等独立容器,这正对应 README 所说的「功能都在独立容器中,使用后才启动」。GetX 可以在 Android、iOS、Web、Mac、Linux、Windows 上以相同代码运行,配合 Get Server 可在后端复用前端代码,配合 Get CLI 可自动化整个开发流程。

安装

将 Get 添加到pubspec.yaml

dependencies: get:

在需要使用的文件中导入:

import 'package:get/get.dart';

GetX 计数器示例:26 行完成状态+路由+共享

Flutter 默认计数器项目有 100 多行,而使用 GetX 重写一个「计数器 Plus 版」只需26 行(含注释),实现:每次点击改变状态、页面切换、跨页面共享状态、业务逻辑与界面分离。

步骤 1:将MaterialApp替换为GetMaterialApp

void main() => runApp(GetMaterialApp(home: Home()));

注意:GetMaterialApp并不是修改后的MaterialApp,而是一个预配置的 Widget,其子组件是默认的MaterialApp。它会创建路由、注入依赖、注入翻译等。如果只用 Get 做状态管理或依赖管理,则没有必要使用GetMaterialApp;只有使用路由管理(Get.to()Get.back()等)时才需要它。

步骤 2:创建业务逻辑类,用.obs让任意变量变为可观察:

class Controller extends GetxController{ var count = 0.obs; increment() => count++; }

步骤 3:创建界面,使用StatelessWidget即可,无需StatefulWidget

class Home extends StatelessWidget { @override Widget build(context) { // 使用Get.put()实例化你的类,使其对当下的所有子路由可用。 final Controller c = Get.put(Controller()); return Scaffold( // 使用Obx(()=>每当改变计数时,就更新Text()。 appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))), // 用一个简单的Get.to()即可代替Navigator.push那8行,无需上下文! body: Center(child: ElevatedButton( child: Text("Go to Other"), onPressed: () => Get.to(Other()))), floatingActionButton: FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment)); } } class Other extends StatelessWidget { // 你可以让Get找到一个正在被其他页面使用的Controller,并将它返回给你。 final Controller c = Get.find(); @override Widget build(context){ // 访问更新后的计数变量 return Scaffold(body: Center(child: Text("${c.count}"))); } }

三大核心功能

状态管理

Get 提供了两个不同的状态管理器:简单的状态管理器(GetBuilder)和响应式状态管理器(GetX / Obx)。二者在 lib/get_state_manager 中实现,其中 get_controllers.dart 定义了GetxController——它合并了原先的 RxController 与 GetBuilder 用法,update()方法会通知监听者刷新 UI,支持按ids精确刷新或通过condition条件控制是否刷新。

响应式状态管理器

GetX 将响应式编程变得极其简单:

  • 不需要创建StreamControllers
  • 不需要为每个变量创建StreamBuilder
  • 不需要为每个状态创建类
  • 不需要为一个初始值创建 getter

把普通变量变为可观察,只需在末尾加上.obs

var name = 'Jonatas Borges'.obs;

在 UI 中监听值变化并自动更新:

Obx(() => Text("${controller.name}"));

就这么多。所有 Rx 类型(RxStringRxIntRxListRxMapRxSet等)都基于 rx_interface.dart 中定义的RxInterface<T>契约实现,它实现了 Flutter 的ValueListenable<T>,因此可以无缝融入 Flutter 的监听机制。

更多细节

深入的状态管理讲解(简单管理器与响应式管理器的区别、更多示例)见 documentation/zh_CN/state_management.md。仓库的 example/lib 演示了使用 GetBuilder/Obx 组织页面数据的完整分层(controllers、views、bindings)。

路由管理

GetX 支持免 context 使用路由、snackbars、dialogs、bottomsheets。同样先替换为GetMaterialApp

GetMaterialApp( // Before: MaterialApp( home: MyHome(), )

常用导航 API:

// 导航到新页面 Get.to(NextScreen()); // 用别名导航到新页面(命名路由详见 documentation/zh_CN/route_management.md) Get.toNamed('/details'); // 关闭 snackbars, dialogs, bottomsheets 或任何通常用 Navigator.pop(context) 关闭的东西 Get.back(); // 进入下一个页面,但没有返回上一页的选项(用于闪屏页、登录页等) Get.off(NextScreen()); // 进入下一个页面并取消之前的所有路由(购物车、投票、测试中很有用) Get.offAll(NextScreen());

核心优势在于:所有导航都不需要 context,可以在 Controller 中直接调用这些方法。路由系统的底层实现在 lib/get_navigation/src/routes,包括GetPageGetRouterDelegateGetInformationParser等;更完整的别名路由与低级路由控制见 documentation/zh_CN/route_management.md。完整的多模块路由示例(含中间件鉴权、抽屉布局)见 example_nav2/lib/app。

依赖管理

Get 的依赖管理器允许用 1 行代码检索到与 Bloc 或 Controller 相同的类,无需 Provider context、无需 InheritedWidget:

Controller controller = Get.put(Controller()); // 而不是 Controller controller = Controller();

注意:如果使用 Get 的状态管理器,请多关注 Bindings API,它能让界面更容易连接到控制器。实例在 Get 实例中创建而非使用类中,因此整个 App 可用:

controller.fetchApi();

在浏览无数条路由后,需要拿回被遗留的控制器数据时:

Controller controller = Get.find(); // 是的,它看起来像魔术,Get会找到你的控制器,并将其提供给你。你可以实例化100万个控制器,Get总会给你正确的控制器。

随后即可恢复数据:

Text(controller.textFromApi);

依赖管理模块在 lib/get_instance 中实现,提供Get.putGet.findGet.lazyPutGet.delete等 API。更多细节见 documentation/zh_CN/dependency_management.md。示例工程中的 Bindings(如 home_binding.dart)展示了如何把依赖注入与路由页面绑定。

实用工具

国际化

翻译被保存为简单的键值字典映射。要添加自定义翻译,创建一个类并继承Translations(基类定义见 internationalization.dart,其keysMap<String, Map<String, String>>):

import 'package:get/get.dart'; class Messages extends Translations { @override Map<String, Map<String, String>> get keys => { 'zh_CN': { 'hello': '你好 世界', }, 'de_DE': { 'hello': 'Hallo Welt', } }; }

使用翻译:将.tr追加到指定的键上,会使用Get.localeGet.fallbackLocale的当前值进行翻译:

Text('title'.tr);

定义语言:向GetMaterialApp传递参数:

return GetMaterialApp( translations: Messages(), // 你的翻译 locale: Locale('zh', 'CN'), // 将会按照此处指定的语言翻译 fallbackLocale: Locale('en', 'US'), // 回调语言选项,以备上面指定的语言翻译不存在 );

改变语言:调用Get.updateLocale(locale),翻译会自动使用新的 locale:

var locale = Locale('en', 'US'); Get.updateLocale(locale);

系统语言:读取系统语言可使用window.locale

import 'dart:ui' as ui; return GetMaterialApp( locale: ui.window.locale, );

仓库还维护了 12 个语言的完整文档与 README 翻译(见 documentation 目录),可对照参考各语言的表述。实际的翻译服务示例见 translation_service.dart。

改变主题

不要使用比GetMaterialApp更高级别的 Widget 来更新主题,否则可能造成键重复。无需创建ThemeProvider

Get.changeTheme(ThemeData.light());

结合「是否深色」的判断 API 与主题更改 API,可实现在onPressed中一键切换:

Get.changeTheme(Get.isDarkMode? ThemeData.light(): ThemeData.dark());

当 darkmode 激活时切换到 light 主题,light 主题激活时切换到 dark 主题。

GetConnect

GetConnect可通过 http 或 websockets 便捷地进行前后台通信,实现在 lib/get_connect。

默认配置

通过 extendGetConnect即可使用 GET/POST/PUT/DELETE/SOCKET 方法与 Rest API 或 websockets 通信:

class UserProvider extends GetConnect { // Get request Future<Response> getUser(int id) => get('http://yourapi/users/$id'); // Post request Future<Response> postUser(Map data) => post('http://yourapi/users', body: data); // Post request with File Future<Response<CasesModel>> postCases(List<int> image) { final form = FormData({ 'file': MultipartFile(image, filename: 'avatar.png'), 'otherFile': MultipartFile(image, filename: 'cover.png'), }); return post('http://yourapi/users/upload', form); } GetSocket userMessages() { return socket('https://yourapi/users/socket'); } }
自定义配置

GetConnect支持配置 baseUrl、响应与请求修饰、权限认证、认证重试次数,以及定义一个标准解码器把响应统一转为模型:

class HomeProvider extends GetConnect { @override void onInit() { // All request will pass to jsonEncode so CasesModel.fromJson() httpClient.defaultDecoder = CasesModel.fromJson; httpClient.baseUrl = 'https://api.covid19api.com'; // baseUrl = 'https://api.covid19api.com'; // It define baseUrl to // Http and websockets if used with no [httpClient] instance // It's will attach 'apikey' property on header from all requests httpClient.addRequestModifier((request) { request.headers['apikey'] = '12345678'; return request; }); // Even if the server sends data from the country "Brazil", // it will never be displayed to users, because you remove // that data from the response, even before the response is delivered httpClient.addResponseModifier<CasesModel>((request, response) { CasesModel model = response.body; if (model.countries.contains('Brazil')) { model.countries.remove('Brazilll'); } }); httpClient.addAuthenticator((request) async { final response = await get("http://yourapi/token"); final token = response.body['token']; // Set the header request.headers['Authorization'] = "$token"; return request; }); //Autenticator will be called 3 times if HttpStatus is //HttpStatus.unauthorized httpClient.maxAuthRetries = 3; } @override Future<Response<CasesModel>> getCases(String path) => get(path); }

注意FormDataMultipartFile等实现位于 lib/get_connect/http/src/multipart,请求修饰、认证等拦截器逻辑位于 lib/get_connect/http/src/interceptors。实际可运行的 Provider/Repository 分层示例见 home_api_provider.dart 与 home_repository.dart。

GetPage 中间件

GetPage有一个新参数,可将列表中的 Get 中间件按指定顺序执行。注意:当 GetPage 有中间件时,所有子 page 会自动继承相同的中间件。中间件的执行顺序在源码 route_middleware.dart 中定义:redirect -> onPageCalled -> onBindingsStart -> onPageBuildStart -> onPageBuilt -> onPageDispose

优先级

设置中间件的priority定义执行顺序:

final middlewares = [ GetMiddleware(priority: 2), GetMiddleware(priority: 5), GetMiddleware(priority: 4), GetMiddleware(priority: -8), ];

-8 => 2 => 4 => 5的顺序执行。底层由MiddlewareRunner对中间件列表按priority升序排序后依次调用(见 route_middleware.dart)。

Redirect

当被调用路由的页面被搜索时调用。它将RouteSettings作为重定向的结果;返回null则不重定向:

RouteSettings redirect(String route) { final authService = Get.find<AuthService>(); return authService.authed.value ? null : RouteSettings(name: '/login') }
onPageCalled

在调用页面、创建任何东西之前调用,可用于更改页面内容或给它一个新页面:

GetPage onPageCalled(GetPage page) { final authService = Get.find<AuthService>(); return page.copyWith(title: 'Welcome ${authService.UserName}'); }
onBindingsStart

在绑定初始化之前调用,可以在此更改页面的绑定:

List<Bindings> onBindingsStart(List<Bindings> bindings) { final authService = Get.find<AuthService>(); if (authService.isAdmin) { bindings.add(AdminBinding()); } return bindings; }
onPageBuildStart

在绑定初始化之后、创建页面 Widget 之前调用:

GetPageBuilder onPageBuildStart(GetPageBuilder page) { print('bindings are ready'); return page; }
onPageBuilt

GetPage.page被调用后触发,接收函数结果并拿到将要显示的 Widget。

onPageDispose

在处理完页面的所有相关对象(Controllers、views 等)之后调用。

一个实际使用中间件做登录鉴权的示例见 auth_middleware.dart,它配合 app_pages.dart 中的GetPage(middlewares: [...])工作。

其他高级 API

// 给出当前页面的args。 Get.arguments //给出以前的路由名称 Get.previousRoute // 给出要访问的原始路由,例如,rawRoute.isFirst() Get.rawRoute // 允许从GetObserver访问Rounting API。 Get.routing // 检查 snackbar 是否打开 Get.isSnackbarOpen // 检查 dialog 是否打开 Get.isDialogOpen // 检查 bottomsheet 是否打开 Get.isBottomSheetOpen // 删除一个路由。 Get.removeRoute() //反复返回,直到表达式返回真。 Get.until() // 转到下一条路由,并删除所有之前的路由,直到表达式返回true。 Get.offUntil() // 转到下一个命名的路由,并删除所有之前的路由,直到表达式返回true。 Get.offNamedUntil() //检查应用程序在哪个平台上运行。 GetPlatform.isAndroid GetPlatform.isIOS GetPlatform.isMacOS GetPlatform.isWindows GetPlatform.isLinux GetPlatform.isFuchsia //检查设备类型 GetPlatform.isMobile GetPlatform.isDesktop //所有平台都是独立支持web的! //你可以知道你是否在浏览器内运行。 //在Windows、iOS、OSX、Android等系统上。 GetPlatform.isWeb // 相当于.MediaQuery.of(context).size.height, 但不可改变。 Get.height Get.width // 提供当前上下文。 Get.context // 在你的代码中的任何地方,在前台提供 snackbar/dialog/bottomsheet 的上下文。 Get.contextOverlay

以下方法是对BuildContext的扩展,可在 UI 代码的任何地方使用:

// 可改变的高度/宽度(桌面或浏览器窗口可缩放时使用) context.width context.height // 让您可以定义一半的页面、三分之一的页面等,对响应式应用很有用。 // 参数: dividedBy (double) 可选 - 默认值:1 // 参数: reducedBy (double) 可选 - 默认值:0 context.heightTransformer() context.widthTransformer() // 类似于 MediaQuery.of(context).size。 context.mediaQuerySize() // 类似于 MediaQuery.of(context).padding。 context.mediaQueryPadding() // 类似于 MediaQuery.of(context).viewPadding。 context.mediaQueryViewPadding() // 类似于 MediaQuery.of(context).viewInsets。 context.mediaQueryViewInsets() // 类似于 MediaQuery.of(context).orientation。 context.orientation() // 检查设备是否处于横向模式 context.isLandscape() // 检查设备是否处于纵向模式。 context.isPortrait() // 类似于MediaQuery.of(context).devicePixelRatio。 context.devicePixelRatio() // 类似于MediaQuery.of(context).textScaleFactor。 context.textScaleFactor() // 查询设备最短边。 context.mediaQueryShortestSide() // 如果宽度大于800,则为真。 context.showNavbar() // 如果最短边小于600p,则为真。 context.isPhone() // 如果最短边大于600p,则为真。 context.isSmallTablet() // 如果最短边大于720p,则为真。 context.isLargeTablet() // 如果当前设备是平板电脑,则为真 context.isTablet() // 根据页面大小返回一个值<T>。 // 可以给值为: // watch:如果最短边小于300 // mobile:如果最短边小于600 // tablet:如果最短边(shortestSide)小于1200 // desktop:如果宽度大于1200 context.responsiveValue<T>()

尺寸与响应式扩展的实现见 context_extensions.dart,平台判断见 platform.dart。

可选的全局设置和手动配置

GetMaterialApp为你配置了一切,但也可以手动配置:

MaterialApp( navigatorKey: Get.key, navigatorObservers: [GetObserver()], );

也可以在GetObserver中使用自己的中间件:

MaterialApp( navigatorKey: Get.key, navigatorObservers: [ GetObserver(MiddleWare.observer) // Here ], );

为 Get 创建全局设置,只需在推送任何路由之前调用Get.config,或在GetMaterialApp中配置:

GetMaterialApp( enableLog: true, defaultTransition: Transition.fade, opaqueRoute: Get.isOpaqueRouteDefault, popGesture: Get.isPopGestureEnable, transitionDuration: Get.defaultDurationTransition, defaultGlobalState: Get.defaultGlobalState, ); Get.config( enableLog = true, defaultPopGesture = true, defaultTransition = Transitions.cupertino )

还可以重定向所有来自 Get 的日志信息,接入自己喜爱的日志包:

GetMaterialApp( enableLog: true, logWriterCallback: localLogWriter, ); void localLogWriter(String text, {bool isError = false}) { // 在这里把信息传递给你最喜欢的日志包。 // 请注意,即使enableLog: false,日志信息也会在这个回调中被推送。 // 如果你想的话,可以通过GetConfig.isLogEnable来检查这个标志。 }

日志机制的基础实现在 log.dart,SmartManagement与全局状态开关定义于 get_interface.dart 与 smart_management.dart。

局部状态组件

这些 Widget 允许你管理单一的值,并保持状态的短暂性和局部性,有 Reactive 和 Simple 两种风格。例如切换TextField的 obscureText、创建自定义可扩展面板、在修改BottomNavigationBar索引的同时改变Scaffold主体内容。

ValueBuilderStatefulWidget的简化,与.setState回调配合并接受更新后的值:

ValueBuilder<bool>( initialValue: false, builder: (value, updateFn) => Switch( value: value, onChanged: updateFn, // 你可以用( newValue )=> updateFn( newValue ) ), // 如果你需要调用 builder 方法之外的东西。 onUpdate: (value) => print("Value updated: $value"), onDispose: () => print("Widget unmounted"), ),

ObxValue:与ValueBuilder类似,但这是响应式版本,需要传入一个 Rx 实例:

ObxValue((data) => Switch( value: data.value, onChanged: data, // Rx 有一个 _callable_ 函数! 你可以使用 (flag) => data.value = flag ), false.obs, ),

有用的提示

.obs可观察对象(也称 Rx Types)有各种内部方法和操作符。

.obs的属性实际值,不要搞错! 我们避免声明变量类型,因为 Dart 编译器足够聪明,且代码更干净,但:

var message = 'Hello world'.obs; print( 'Message "$message" has Type ${message.runtimeType}');

即使messageprints实际的字符串值,其类型也是RxString!所以不能直接message.substring(0, 4),必须在 observable 内部访问真正的value。最常用的是.value,但还有更多玩法:

final name = 'GetX'.obs; // 只有在值与当前值不同的情况下,才会 "更新 "流。 name.value = 'Hey'; // 所有Rx属性都是 "可调用 "的,并返回新的值。 // 但这种方法不接受 "null",UI将不会重建。 name('Hello'); // 就像一个getter,打印'Hello'。 name(); ///数字。 final count = 0.obs; // 您可以使用num基元的所有不可变操作! count + 1; // 注意!只有当 "count "不是final时,这才有效,除了var count += 1; // 你也可以与数值进行比较。 count > 2; /// booleans: final flag = false.obs; // 在真/假之间切换数值 flag.toggle(); /// 所有类型。 // 将 "value "设为空。 flag.nil(); // 所有的toString()、toJson()操作都会向下传递到`value`。 print( count ); // 在内部调用 "toString()" 来 GetRxInt final abc = [0,1,2].obs; // 将值转换为json数组,打印RxList。 // 所有Rx类型都支持Json! print('json: ${jsonEncode(abc)}, type: ${abc.runtimeType}'); // RxMap, RxList 和 RxSet 是特殊的 Rx 类型,扩展了它们的原生类型。 // 但你可以像使用普通列表一样使用列表,尽管它是响应式的。 abc.add(12); // 将12添加到列表中,并更新流。 abc[3]; // 和Lists一样,读取索引3。 // Rx和值是平等的,但hashCode总是从值中提取。 final number = 12.obs; print( number == 12 ); // prints > true ///自定义Rx模型。 // toJson(), toString()都是递延给子代的,所以你可以在它们上实现覆盖,并直接print()可观察的内容。 class User { String name, last; int age; User({this.name, this.last, this.age}); @override String toString() => '$name $last, $age years old'; } final user = User(name: 'John', last: 'Doe', age: 33).obs; // `user`是 "响应式 "的,但里面的属性却不是! // 所以,如果我们改变其中的一些变量: user.value.name = 'Roi'; // 小部件不会重建! // 对于自定义类,我们需要手动 "通知 "改变。 user.refresh(); // 或者我们可以使用`update()`方法! user.update((value){ value.name='Roi'; }); print( user );
GetView

GetView是一个对已注册 Controller 提供名为controller的 getter 的const StatelessWidget(实现见 get_view.dart):

class AwesomeController extends GetxController { final String title = 'My Awesome View'; } // 一定要记住传递你用来注册控制器的`Type`! class AwesomeView extends GetView<AwesomeController> { @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(20), child: Text( controller.title ), // 只需调用 "controller.something" ); } }
GetWidget

GetWidget的用例非常少见且特殊:它「缓存」了一个 Controller,由于缓存的存在,不能成为const Stateless

什么时候需要缓存一个 Controller?如果你使用了Get.create()

Get.create(()=>Controller())会在每次调用Get.find<Controller>()时生成一个新的 Controller。使用GetWidget可以保存 Todo 项目列表,即使 Widget 被「重建」,也会保持相同的控制器实例。

GetxService

GetxServiceGetxController共享相同生命周期(onInit()onReady()onClose()),但内部没有「逻辑」,它只是通知 GetX 的依赖注入系统:这个子类不能从内存中删除。所以它对于保持ApiServiceStorageServiceCacheService等服务始终可被Get.find()获取并保持运行非常有用:

Future<void> main() async { await initServices(); /// 等待服务初始化. runApp(SomeApp()); } /// 在运行Flutter应用之前让服务初始化是明智之举, /// 因为你可以控制执行流程(也许你需要加载一些主题配置、apiKey、用户自定义的语言等, /// 所以在运行ApiService之前加载SettingService)。 void initServices() async { print('starting services ...'); ///这里是你放get_storage、hive、shared_pref初始化的地方。 ///或者moor连接,或者其他什么异步的东西。 await Get.putAsync(() => DbService().init()); await Get.putAsync(SettingsService()).init(); print('All services started...'); } class DbService extends GetxService { Future<DbService> init() async { print('$runtimeType delays 2 sec'); await 2.delay(); print('$runtimeType ready!'); return this; } } class SettingsService extends GetxService { void init() async { print('$runtimeType delays 1 sec'); await 1.delay(); print('$runtimeType ready!'); } }

实际删除一个GetxService的唯一方法是使用Get.reset(),它就像「热重启」你的应用。如果需要在应用生命周期内对类实例绝对持久化,请使用GetxService

从 2.0 开始的兼容性变化

1. Rx 类型改名

BeforeAfter
StringXRxString
IntXRxInt
MapXRxMap
ListXRxList
NumXRxNum
DoubleXRxDouble

现在RxControllerGetBuilder已合并,你不再需要记住用哪个控制器,只要用GetxController即可,它同时支持简单状态管理与响应式。

2. 别名路由

之前:

GetMaterialApp( namedRoutes: { '/': GetRoute(page: Home()), } )

现在:

GetMaterialApp( getPages: [ GetPage(name: '/', page: () => Home()), ] )

为什么这样改?通常可能需要通过一个参数或登录令牌来决定显示哪个页面。将页面插入函数中,大大降低了 RAM 消耗——应用启动后路由不会在内存中分配:

GetStorage box = GetStorage(); GetMaterialApp( getPages: [ GetPage(name: '/', page:(){ return box.hasData('token') ? Home() : Login(); }) ] )

为什么选择 GetX

  1. 依赖集中、兼容统一:Flutter 更新常导致多个包损坏。Get 将开发的主要资源(状态、依赖和路由管理)集中在同一个包中,Flutter 更新后只需更新 Get 依赖即可继续工作,且不存在多包版本互相不兼容的问题。
  2. 极简 API:如Get.to(Home())一行完成导航,.obs+Obx完成状态响应,动态网页 URL 处理也非常简单。
  3. 自动内存管理(SmartManagement):所有不被使用的控制器会从内存中自动删除,保证只消耗最低限度的必要资源。
  4. 实际解耦:控制器拥有独立生命周期(如onInit启动 http 调用、数据到达后填充变量),UI 人员只需处理 Widget 与用户事件,业务逻辑人员可以自由地单独创建和测试业务逻辑。

总结

GetX 以「状态管理 + 依赖注入 + 路由管理」三位一体的方式解决了 Flutter 开发中的高频痛点,并通过 GetMaterialApp、GetConnect、GetPage 中间件、国际化、主题切换与丰富的上下文扩展工具提供了完整的应用开发闭环。从本仓库的 example 与 example_nav2 两个示例工程可以看到从简单计数器到多模块、带鉴权中间件的完整应用结构,而 documentation 目录下各语言的专项文档(state_management.md、route_management.md、dependency_management.md)可作为深入学习的下一站。

  • 前端

【免费下载链接】getx

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.

项目地址:https://gitcode.com/gh_mirrors/ge/getx
点击查看免费下载
上一篇:Sandboxie异常检测机制:识别可疑应用行为模式
下一篇:EMQX消息积压处理:队列机制与流量控制

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询