Flutter视图模型管理插件view_model_kit的使用
Flutter视图模型管理插件view_model_kit的使用
view_model_kit
是一个简单的视图模型和状态管理库。以下是其使用方法的详细说明。
如何使用
请参阅示例代码。
1. 设置 StatefulWidget 并创建 ViewModel
main_page.dart
class MainPage extends StatefulWidget {
const MainPage({super.key});
[@override](/user/override)
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends StateWithViewModel<MainPage, MainViewModel> {
[@override](/user/override)
MainViewModel createViewModel() => MainViewModel();
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Main Page')),
body: Center(
child: Column(
children: [
Text("Count: ${viewModel.count.value}"),
Text("Todos: ${viewModel.todos.value.map((e) => e.title).join(', ')}"),
],
),
),
);
}
}
main_view_model.dart
class MainViewModel extends BaseViewModel {
late final _count = createMutable(0); // 可以修改。
R<int> get count => _count; // 不可修改。
late final _todos = createMutableList<Todo>(); // 或者 createMutableList<Todo>([]);
RList<Todo> get todos => _todos; // 不可修改。
[@override](/user/override)
void onReady() async {
_count.value = 1; // 自动重建。
_count.value++; // 自动重建。
// count.value = 1; // 错误。因为 count 的类型是 R<V>。应该使用 MutableR<V>.value = 1;
final todos = await getTodosFromRemote();
_todos.addAll([...todos]); // 自动重建。
// todo.addAll([...todos]); // 错误。因为 todos 的类型是 RList<V>。应该使用 MutableRList<V>.addAll;
// 但是...
print(_todos.value); // 正确
print(_todos.value.addAll([...todos])); // 不重建。应该使用 todos.addAll([...todos]);
}
}
2. 使用 R<V>
或 RList<V>
与 ViewModel 结合
main_view_model.dart
class MainViewModel extends BaseViewModel {
late final _count = createMutable(0); // 可以修改。
R<int> get count => _count; // 不可修改。
late final _todos = createMutableList<Todo>(); // 或者 createMutableList<Todo>([]);
RList<Todo> get todos => _todos; // 不可修改。
[@override](/user/override)
void onReady() async {
_count.value = 1; // 自动重建。
_count.value++; // 自动重建。
// count.value = 1; // 错误。因为 count 的类型是 R<V>。应该使用 MutableR<V>.value = 1;
final todos = await getTodosFromRemote();
_todos.addAll([...todos]); // 自动重建。
// todo.addAll([...todos]); // 错误。因为 todos 的类型是 RList<V>。应该使用 MutableRList<V>.addAll;
// 但是...
print(_todos.value); // 正确
print(_todos.value.addAll([...todos])); // 不重建。应该使用 todos.addAll([...todos]);
}
}
3. 在 StateWithViewModel
中使用 R<V>
或 RList<V>
与 Widget 结合
main_page.dart
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
Text("${viewModel.count.value}"),
Text("${viewModel.todos.value.map((e) => e.title).join(', ')}"),
],
),
),
);
}
4. 最小化重建
main_page.dart
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
SelectBuilder(
rx: viewModel.count,
builder: (context, count) => Text("$count (仅此部件重建)"), // 当更新时仅重建此部件
),
Text("${viewModel.count.value} (不重建)"),
],
),
),
);
}
5. 全局状态管理容器
在本示例中,我们使用了 GetIt
进行全局状态管理。
main_container.dart
class MainContainer extends BaseContainer {
late final _globalCount = createMutable(0);
R<int> get globalCount => _globalCount;
void incrementGlobalCount() {
_globalCount.value++;
}
}
main.dart
void main() {
GetIt.instance.registerLazySingleton(() => MainContainer());
runApp(MyApp());
}
counter1_page.dart
class Counter1Page extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
final container = GetIt.instance.get<MainContainer>();
return Scaffold(
body: Center(
child: SelectBuilder(
rx: container.globalCount,
builder: (context, value) => ElevatedButton(
child: Text("Page1 count up : $value"),
onPressed: () => container.incrementGlobalCount(),
),
),
),
);
}
}
counter2_page.dart
class Counter2Page extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
final container = GetIt.instance.get<MainContainer>();
return Scaffold(
body: Center(
child: SelectBuilder(
rx: container.globalCount,
builder: (context, value) => ElevatedButton(
child: Text("Page2 count up : $value"),
onPressed: () => container.incrementGlobalCount(),
),
),
),
);
}
}
6. 观察器
observe_test_page.dart
class ObserveTestPage extends StatefulWidget {
const ObserveTestPage({super.key});
[@override](/user/override)
State<ObserveTestPage> createState() => _ObserveTestPageState();
}
class _ObserveTestPageState extends StateWithViewModel<ObserveTestPage, ObserveTestViewModel> {
[@override](/user/override)
ObserveTestViewModel createViewModel() => ObserveTestViewModel();
final mainContainer = GetIt.instance.get<MainContainer>();
[@override](/user/override)
void initState() {
super.initState();
/// viewModel.counter 生命周期与这个有状态部件相同。没有观察器。
viewModel.counter.observe((v) => print("counter value changed! : $v"));
/// 但是,mainContainer.globalCount 生命周期非常不同(不依赖于这个有状态部件)
/// 这意味着当销毁时必须取消观察。
mainContainer.globalCount.observe(observeGlobalCount);
}
void observeGlobalCount(int v) {
print("globalCount value changed! : $v");
}
[@override](/user/override)
void dispose() {
mainContainer.globalCount.cancelObserve(observeGlobalCount);
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return const Placeholder();
}
}
更多关于Flutter视图模型管理插件view_model_kit的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter视图模型管理插件view_model_kit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
view_model_kit
是一个用于 Flutter 的状态管理插件,它提供了一种简化的方式来管理视图模型(ViewModel)和状态。使用 view_model_kit
可以帮助你更好地分离业务逻辑和 UI 代码,使代码更加清晰和可维护。
以下是如何使用 view_model_kit
的基本步骤:
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加 view_model_kit
依赖:
dependencies:
flutter:
sdk: flutter
view_model_kit: ^latest_version
然后运行 flutter pub get
来安装依赖。
2. 创建 ViewModel
创建一个继承自 ViewModel
的类,并在其中定义你的业务逻辑和状态。
import 'package:view_model_kit/view_model_kit.dart';
class CounterViewModel extends ViewModel {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 通知监听器状态已改变
}
}
3. 在 UI 中使用 ViewModel
在你的 UI 中,使用 ViewModelProvider
来提供 ViewModel,并使用 ViewModelBuilder
来监听 ViewModel 的状态变化。
import 'package:flutter/material.dart';
import 'package:view_model_kit/view_model_kit.dart';
import 'counter_view_model.dart'; // 导入你定义的 ViewModel
class CounterPage extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return ViewModelProvider(
create: () => CounterViewModel(),
child: Scaffold(
appBar: AppBar(
title: Text('Counter App'),
),
body: Center(
child: ViewModelBuilder<CounterViewModel>(
builder: (context, viewModel) {
return Text(
'Count: ${viewModel.count}',
style: TextStyle(fontSize: 24),
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 获取 ViewModel 并调用方法
ViewModelProvider.of<CounterViewModel>(context).increment();
},
child: Icon(Icons.add),
),
),
);
}
}