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),
        ),
      ),
    );
  }
}
回到顶部