Flutter MVVM架构与状态管理插件maac_mvvm_with_riverpod的使用
Flutter MVVM架构与状态管理插件maac_mvvm_with_riverpod的使用

maac_mvvm_with_riverpod 是一个扩展包,用于与 RiverPod 一起使用的 maac_mvvm 包。此包保留了 maac_mvvm 包中的架构和组件,如 ViewModel、StreamData 和 ViewModelWidget,并添加了支持 RiverPod 的额外组件,如 ConsumerViewModelWidget 和 RiverViewModel。
它简单、干净且易于实现。
请参阅 maac_mvvm
特性
ConsumerViewModelWidget
用于构建绑定到 ViewModel 的 UI 小部件的地方。
RiverViewModel
持有与其绑定的小部件的逻辑和生命周期,并继承自 maac_mvvm 的 ViewModel 类。
开始使用
安装
在 pubspec.yaml 文件中安装:
flutter pub add maac_mvvm_with_riverpod
使用方法
1 - 安装包
flutter pub add maac_mvvm_with_riverpod
2 - 创建你的 ViewModel
通过继承 RiverViewModel 来创建 ViewModel,以便管理小部件的逻辑和生命周期。此 ViewModel 将可以访问 RiverViewModel 中定义的状态和方法,以及 maac_mvvm 的 ViewModel 中定义的方法。以下是一个简单的 ViewModel,用于从小部件中增加计数器。
final _exampleUIStateProvider = StateProvider.autoDispose<ExamplePageUIState>((ref) {
return ExamplePageUIState();
});
final exampleViewModelProvider = Provider.autoDispose<ExamplePageViewModel>((ref) {
return ExamplePageViewModel(uiState: ref.watch(_exampleUIStateProvider.notifier));
});
class ExamplePageUIState {
int counter;
ExamplePageUIState({this.counter = 0});
ExamplePageUIState copyWith({int? counter}) {
return ExamplePageUIState(
counter: counter ?? this.counter,
);
}
}
class ExamplePageViewModel extends RiverViewModel<ExamplePageUIState> {
ExamplePageViewModel({required super.uiState});
}
3 - 创建绑定到 ViewModel 的小部件
ConsumerViewModelWidget 只包含两个方法:createViewModel 和 build。
buildWidget
方法用于构建界面。viewModelProvider
方法用于提供 ViewModel 提供者。
与 maac_mvvm 类似,我们不必担心小部件的其他生命周期,因为它们会根据 ViewModel 自动调用。
class ExamplePage extends ConsumerViewModelWidget<ExamplePageViewModel> {
const ExamplePage({super.key});
[@override](/user/override)
AutoDisposeProvider<ExamplePageViewModel> viewModelProvider() => exampleViewModelProvider;
[@override](/user/override)
Widget buildWidget(BuildContext context, WidgetRef ref, ExamplePageViewModel viewModel) {
return BuildYourPageWidget();
}
}
如果小部件有传递的属性并且需要传递给 ViewModel,我们可以覆盖 awake 方法。
awake 方法将在 ViewModelWidget 的 createViewModel 方法之后立即调用,并在 ViewModel 的 onInitState 方法之前调用。这将有助于设置必要的数据。
class ExamplePage extends ConsumerViewModelWidget<ExamplePageViewModel> {
final int initValue;
const ExamplePage({super.key, required this.initValue});
[@override](/user/override)
AutoDisposeProvider<ExamplePageViewModel> viewModelProvider() => exampleViewModelProvider;
[@override](/user/override)
void awake(WidgetRef ref, ExamplePageViewModel viewModel) => viewModel.setup(initValue);
[@override](/user/override)
Widget buildWidget(BuildContext context, WidgetRef ref, ExamplePageViewModel viewModel) {
return BuildYourPageWidget();
}
}
4 - 监听来自 ViewModel 的数据更改
要从 ViewModel 中监听数据更改,我们可以使用 RiverPod 提供的组件。由于 RiverPod 是一个状态管理库,我们可以使用默认的 RiverViewModel 中提供的 StateController 来更新 UI。
在以下示例中,ExamplePageViewModel 将增加计数器并通过 uiState
更新 UI。ViewModel 还将暴露 counterSelector
供 Widget 监听并更新。
class ExamplePageViewModel extends RiverViewModel<ExamplePageUIState> {
ExamplePageViewModel({required super.uiState});
final counterSelector = _exampleUIStateProvider.select((value) => value.counter);
void incrementCounter() {
uiState.update((state) => state.copyWith(counter: state.counter + 1));
}
}
您可以使用 RiverPod 提供的组件(例如 ConsumerWidget)来更新 UI。
class ExampleCounterText extends ConsumerWidget {
const ExampleCounterText({super.key});
[@override](/user/override)
Widget build(BuildContext context, WidgetRef ref) {
final viewModel = ref.watch(exampleViewModelProvider);
final counter = ref.watch(viewModel.counterSelector);
return Text(
'$counter',
style: Theme.of(context).textTheme.headlineMedium,
);
}
}
完整示例
class ExamplePage extends ConsumerViewModelWidget<ExamplePageViewModel> {
const ExamplePage({super.key});
[@override](/user/override)
AutoDisposeProvider<ExamplePageViewModel> viewModelProvider() => exampleViewModelProvider;
[@override](/user/override)
Widget buildWidget(BuildContext context, WidgetRef ref, ExamplePageViewModel viewModel) {
final counter = ref.watch(viewModel.counterSelector);
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
// 监听 counterSelector 更新 UI
Consumer(
builder: (context, ref, child) {
final counter = ref.watch(viewModel.counterSelector);
return Text(
'$counter',
style: Theme.of(context).textTheme.headlineMedium,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: viewModel.incrementCounter, // 调用 ViewModel 中的 incrementCounter 函数
tooltip: 'Increment',
child: const Icon(Icons.add),
), // 这个尾随逗号使自动格式化更美观
);
}
}
final _exampleUIStateProvider = StateProvider.autoDispose<ExamplePageUIState>((ref) {
return ExamplePageUIState();
});
final exampleViewModelProvider = Provider.autoDispose<ExamplePageViewModel>((ref) {
return ExamplePageViewModel(uiState: ref.watch(_exampleUIStateProvider.notifier));
});
class ExamplePageUIState {
int counter;
ExamplePageUIState({this.counter = 0});
ExamplePageUIState copyWith({int? counter}) {
return ExamplePageUIState(
counter: counter ?? this.counter,
);
}
}
class ExamplePageViewModel extends RiverViewModel<ExamplePageUIState> {
ExamplePageViewModel({required super.uiState});
// 暴露一个选择器供 Widget 监听和更新
final counterSelector = _exampleUIStateProvider.select((value) => value.counter);
void incrementCounter() {
// 更新 uiState 以反映新的计数值
uiState.update((state) => state.copyWith(counter: state.counter + 1));
}
}
更多关于Flutter MVVM架构与状态管理插件maac_mvvm_with_riverpod的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter MVVM架构与状态管理插件maac_mvvm_with_riverpod的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,MVVM(Model-View-ViewModel)是一种常见的架构模式,用于分离UI逻辑和业务逻辑。maac_mvvm_with_riverpod
是一个结合了MVVM架构和状态管理插件 Riverpod
的库,它帮助开发者更轻松地实现MVVM模式。
MVVM 架构概述
- Model: 负责数据层,通常包括数据获取、存储和处理。
- View: 负责UI层,展示数据和接收用户输入。
- ViewModel: 作为View和Model之间的桥梁,处理业务逻辑,并将数据转换为View可以使用的形式。
Riverpod 概述
Riverpod
是Flutter中一个强大的状态管理库,它是Provider
的改进版,提供了更好的类型安全性和灵活性。
maac_mvvm_with_riverpod 的使用
1. 添加依赖
首先,在pubspec.yaml
中添加maac_mvvm_with_riverpod
依赖:
dependencies:
flutter:
sdk: flutter
maac_mvvm_with_riverpod: ^1.0.0
然后运行flutter pub get
安装依赖。
2. 创建 Model
Model
通常是一个简单的数据类,负责数据的存储和处理。
class User {
final String name;
final int age;
User(this.name, this.age);
}
3. 创建 ViewModel
ViewModel
继承自 ChangeNotifier
或使用 Riverpod
的 StateNotifier
,负责处理业务逻辑。
import 'package:maac_mvvm_with_riverpod/maac_mvvm_with_riverpod.dart';
class UserViewModel extends ChangeNotifier {
User? _user;
User? get user => _user;
void fetchUser() {
// 模拟数据获取
_user = User("John Doe", 30);
notifyListeners();
}
}
4. 使用 Riverpod 管理状态
使用 Riverpod
来管理 ViewModel
的状态。
import 'package:flutter_riverpod/flutter_riverpod.dart';
final userViewModelProvider = ChangeNotifierProvider<UserViewModel>((ref) {
return UserViewModel();
});
5. 创建 View
在 View
中,使用 Consumer
或 ConsumerWidget
来监听 ViewModel
的状态变化。
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class UserView extends ConsumerWidget {
[@override](/user/override)
Widget build(BuildContext context, WidgetRef ref) {
final userViewModel = ref.watch(userViewModelProvider);
return Scaffold(
appBar: AppBar(
title: Text('User Profile'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (userViewModel.user != null)
Text('Name: ${userViewModel.user!.name}'),
if (userViewModel.user != null)
Text('Age: ${userViewModel.user!.age}'),
ElevatedButton(
onPressed: () {
userViewModel.fetchUser();
},
child: Text('Fetch User'),
),
],
),
),
);
}
}
6. 运行应用
在 main.dart
中运行应用。
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'user_view.dart';
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'MVVM with Riverpod',
home: UserView(),
);
}
}