Flutter命令行工具插件commandy的使用
Flutter命令行工具插件commandy的使用
Commandy
Commandy 是一个为 Flutter 设计的包,旨在简化异步命令的执行和管理,同时提供一种清晰且一致的方式来处理成功、失败和状态变化。它帮助你抽象出异步操作的复杂性,使你的代码更加模块化、可测试和可维护。
关键特性 🚀
-
统一的结果处理: 使用
Result
模型,其中包含Success<T>
和FailureResult<T>
变体来明确表示操作结果。这鼓励采用函数式错误处理方法,并使代码更容易理解。 -
异步命令:
Command<T, Params>
封装了异步操作,通过ValueNotifier
通知执行状态变化(isExecuting
),并通过ValueNotifier
传递结果Result<T>
。这种模式使得将异步逻辑集成到 ViewModels 或 UseCases 中变得简单。 -
基于流的命令:
StreamCommand<T, Params>
处理返回Stream<Result<T>>
的操作,自动管理订阅并提供更新通过ValueNotifier
。这非常适合持续更新的数据源,如实时查询或传感器数据。 -
用于 UI 的命令监听器:
CommandListener
小部件易于集成到 Flutter UI 代码中。它监听多个命令并在结果变化时触发回调,允许 UI 层立即响应新数据或错误。 -
无参数简化: 提供了一种方便的方式来管理不需要参数的命令,避免了空值或不必要的复杂性。
-
状态管理就绪: 虽然 Commandy 主要关注于命令,但它也可以作为轻量级的状态管理解决方案使用。通过在命令中封装业务逻辑和状态更改,你获得了一个干净且可测试的方法来管理应用程序状态。
安装 💻
在 pubspec.yaml
文件中添加 Commandy:
dependencies:
commandy: ^0.1.0
然后,获取包:
flutter pub get
开始使用
- 导入库:
import 'package:commandy/commandy.dart';
-
创建一个命令,该命令执行你的异步逻辑,例如从仓库中获取数据。
-
将其绑定到 UI,使用
CommandListener
小部件或通过调用execute
并在 ViewModel 中监听结果变化。
通过将应用程序的异步操作结构化为返回结果的命令,你可以保持清晰的关注点分离,并确保逻辑和 UI 保持松耦合。
核心概念
结果及其变体
Result<T>
是一个密封类,代表操作的结果。它有两个主要变体:
Success<T>
:表示操作成功完成。持有结果数据。FailureResult<T>
:表示操作失败。持有包含错误消息、可选异常和堆栈跟踪的Failure
对象。
NoParams 类 🛠️
NoParams
是一个轻量级类,表示命令没有参数。它有助于即使没有参数的情况下也保持 Command<T, Params>
接口的一致性。
示例用法:
final incrementCommand = Command<int, NoParams>((_) async {
// 增量逻辑
await Future.delayed(const Duration(seconds: 1));
return Success(42);
});
// 执行命令
await incrementCommand.execute(const NoParams());
这避免了传递 null
,并确保代码库中的清晰性和一致性。
命令
封装异步操作并通过 ValueNotifier
更新其状态:
isExecuting
:一个ValueNotifier<bool>
,指示命令是否仍在运行。result
:一个ValueNotifier<Result<T>?>
,保存最后一个结果。
使用 Command
进行一次性操作,如登录请求或数据获取。
StreamCommand
与流一起工作并管理持续更新。调用 start(params)
开始监听,调用 stop()
取消订阅。
CommandListener
通过反应命令结果的变化简化 UI 集成。与其手动监听 ValueNotifier
,不如使用 CommandListener
来高效地处理更新。
高级功能 ⚡
ViewModelSelector 🧩
ViewModelSelector
是一个强大的工具,根据 ChangeNotifier
基础 ViewModel 的特定属性选择性地重建 Flutter 小部件。它通过确保只有依赖选定值的小部件被重建来优化 UI 更新,从而避免在 ViewModel 中其他属性更改时进行不必要的小部件重建。
关键特性:
-
选择性重建: 使用
selector
函数从 ViewModel 中提取特定属性,并仅在该属性更改时触发重建。 -
与 ChangeNotifier 集成: 无缝工作于现有的 ViewModels,这些 ViewModels 扩展
ChangeNotifier
。 -
高效和模块化: 允许更细粒度的 UI 更新控制,而无需外部库或工具。
示例用法:
1. 创建一个 ViewModel:
class MyViewModel extends ChangeNotifier {
String _name = 'John Doe';
int _counter = 0;
String get name => _name;
int get counter => _counter;
void updateName(String newName) {
_name = newName;
notifyListeners();
}
void incrementCounter() {
_counter++;
notifyListeners();
}
}
2. 在你的小部件中使用 ViewModelSelector:
final myViewModel = MyViewModel();
ViewModelSelector<MyViewModel, String>(
viewModel: myViewModel,
selector: (vm) => vm.name, // 仅观察 `name` 属性
builder: (context, name) {
return Text('Name: $name');
},
);
ViewModelSelector<MyViewModel, int>(
viewModel: myViewModel,
selector: (vm) => vm.counter, // 仅观察 `counter` 属性
builder: (context, counter) {
return Text('Counter: $counter');
},
);
收益:
- 确保 UI 效率,通过仅重建受影响的小部件来响应状态更改。
- 与现有的
ChangeNotifier
架构简单且干净地集成。 - 当处理复杂的 ViewModels 时,非常适合模块化 UI 更新。
示例 🎯
计数器示例
final incrementCommand = Command<int, NoParams>((_) async {
// 增量逻辑
await Future.delayed(Duration(seconds: 1));
return Success(42);
});
计时器示例
final timerCommand = StreamCommand<int, NoParams>((_) {
return Stream.periodic(Duration(seconds: 1), (x) => 30 - x - 1)
.take(30)
.map((value) => Success(value));
});
timerCommand.start(const NoParams());
完整实现
查看 example 文件夹中的完整实现,包括计数器和计时器示例的 UI 集成和详细逻辑。
额外资源 📚
了解更多关于命令模式及其实际应用:
错误处理 🚦
将所有错误转换为 FailureResult
实例:
final safeCommand = Command<int, int>((param) async {
try {
if (param < 0) throw Exception('Negative param');
return Success(param * 2);
} catch (e, s) {
return FailureResult<int>(
Failure(message: 'Error processing param', exception: e, stackTrace: s),
);
}
});
更多关于Flutter命令行工具插件commandy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html