quanttide / quanttide-handbook-of-flutter

量潮Flutter手册
https://quanttide.github.io/quanttide-handbook-of-flutter/
0 stars 0 forks source link

MVVM模式和视图模型ViewModel的实现 #6

Closed Guo-Zhang closed 1 year ago

Guo-Zhang commented 1 year ago

在Flutter中,可以使用provider包来实现MVVM模式。下面是使用provider定义一个ViewModel的一般步骤:

  1. 首先,导入provider包:

    import 'package:provider/provider.dart';
  2. 创建一个继承自ChangeNotifier的ViewModel类,并在其中定义需要管理的状态和相应的操作方法。ChangeNotifierprovider包提供的用于实现状态管理的基类。

class MyViewModel extends ChangeNotifier {
  String _message = '';

  String get message => _message;

  void updateMessage(String newMessage) {
    _message = newMessage;
    notifyListeners(); // 通知监听者,即视图,数据已更新
  }
}

在上面的例子中,MyViewModel类维护了一个message状态,并提供了一个updateMessage方法用于更新该状态。在状态更新后,通过调用notifyListeners()方法通知视图更新。

  1. 在Flutter的Widget树中使用Provider来提供ViewModel实例,并在需要使用ViewModel的地方使用Consumer来订阅状态的变化。
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => MyViewModel(),
      child: Consumer<MyViewModel>(
        builder: (context, viewModel, child) {
          return Scaffold(
            body: Center(
              child: Text(viewModel.message),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                viewModel.updateMessage('Hello, MVVM!');
              },
              child: Icon(Icons.add),
            ),
          );
        },
      ),
    );
  }
}

在上面的例子中,ChangeNotifierProvider用于提供ViewModel的实例,Consumer用于订阅ViewModel的状态变化。在builder回调函数中,可以根据ViewModel的状态来构建相应的UI。

当调用viewModel.updateMessage方法更新message状态时,Consumer会重新构建其子树,从而更新UI。

这就是使用provider包在Flutter中定义一个ViewModel的一般过程。通过使用provider,可以方便地实现状态管理和视图更新,实现MVVM模式的开发。

Guo-Zhang commented 1 year ago

https://codewithandrea.com/videos/flutter-state-management-setstate-freezed-state-notifier-provider/

Guo-Zhang commented 1 year ago

https://pub.dev/packages/state_notifier

Guo-Zhang commented 1 year ago

是否需要把APIClient的逻辑并入ViewModel或者Model?

由于我们的API是围绕Model的REST API,因此APIClient的写法不是最优雅的方案,也不太方便和本地存储统一。

有两种方案。

  1. 和本地存储、网络请求相关的实现都写到Model里,在ViewModel调用。
  2. 都写在ViewModel里。

倾向于方案1,不过如何改进现有的API调用方案还需要考虑。

Guo-Zhang commented 1 year ago

ViewModel在REST的设计下也有标准化的可能。

假设有一个模型Model,那么可以确定的ViewModel有list和detail。

难以解决的问题是创建逻辑。创建逻辑需要list的API,但是和detail一样需要处理单个数据的具体值。因此用其中一个或者单独一个似乎都可以。

Guo-Zhang commented 1 year ago

计划使用BLoC模式实现。