Flutter MVVM架构插件umvvm的使用
Flutter MVVM架构插件umvvm的使用
UMVVM库
UMVVM库是一组用于Flutter应用架构的类。
安装
在 pubspec.yaml 文件中添加以下依赖项:
dependencies:
umvvm: ^<最新版本>
dev_dependencies:
umvvm_generator: ^<最新版本>
如果你还没有安装 build_runner,还需要添加以下依赖项:
dev_dependencies:
build: ^<最新版本>
build_config: ^<最新版本>
build_runner: ^<最新版本>
要构建或重新生成生成的文件,请运行以下命令:
flutter pub run build_runner build --delete-conflicting-outputs
示例
最小示例可以在 这里 找到。
更复杂的示例可以在 这里 找到。这些示例包括基本组件的使用、导航示例和数据库连接示例。
文档
以下是一个小示例,演示了所有组件的使用:
import 'package:dart_mappable/dart_mappable.dart';
import 'package:dio/dio.dart' as dio;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:umvvm/umvvm.dart';
part 'main.api.dart';
part 'main.mvvm.dart';
part 'main.mapper.dart';
class PostLikedEvent {
final int id;
const PostLikedEvent({
required this.id,
});
}
[@MappableClass](/user/MappableClass)()
class Post with PostMappable {
const Post({
required this.title,
required this.body,
required this.id,
this.isLiked = false,
});
final String? title;
final String? body;
final int? id;
final bool isLiked;
static const fromMap = PostMapper.fromMap;
}
[@MappableClass](/user/MappableClass)()
class PostsState with PostsStateMappable {
const PostsState({
this.posts,
});
final StatefulData<List<Post>>? posts;
}
[@mainApi](/user/mainApi)
class Apis with ApisGen {}
[@mainApp](/user/mainApp)
class App extends UMvvmApp with AppGen {
final apis = Apis();
[@override](/user/override)
Future<void> initialize() async {
await super.initialize();
}
}
final app = App();
Future<void> main() async {
await app.initialize();
runApp(const MaterialApp(home: PostsListView()));
}
class HttpRequest<T> extends DioRequest<T> {
[@override](/user/override)
RequestSettings get defaultSettings => RequestSettings(
logPrint: (message) {
print(message);
},
exceptionPrint: (error, trace) {
print(error);
print(trace);
},
);
}
[@api](/user/api)
class PostsApi {
HttpRequest<List<Post>> getPosts(int offset, int limit) =>
HttpRequest<List<Post>>()
..method = RequestMethod.get
..baseUrl = 'http://jsonplaceholder.typicode.com'
..url = '/posts'
..parser = (result, headers) async {
final list = <Post>[];
result?.forEach((data) {
list.add(Post.fromMap(data));
});
return list;
};
}
[@basicInstance](/user/basicInstance)
class PostsInteractor extends BaseInteractor<PostsState, Map<String, dynamic>?> {
Future<void> loadPosts(int offset, int limit, {bool refresh = false}) async {
updateState(state.copyWith(posts: const LoadingData()));
late Response<List<Post>> response;
if (refresh) {
response = await executeAndCancelOnDispose(app.apis.posts.getPosts(0, limit));
} else {
response = await executeAndCancelOnDispose(app.apis.posts.getPosts(offset, limit));
}
if (response.isSuccessful) {
updateState(state.copyWith(posts: SuccessData(result: response.result ?? [])));
} else {
updateState(state.copyWith(posts: ErrorData(error: response.error)));
}
}
[@override](/user/override)
List<EventBusSubscriber> subscribe() => [
on<PostLikedEvent>((event) {
// 更新帖子列表...
}),
];
[@override](/user/override)
PostsState get initialState => const PostsState();
}
class PostsListViewState {}
class PostsListViewModel extends BaseViewModel<PostsListView, PostsListViewState> {
[@override](/user/override)
DependentMvvmInstanceConfiguration get configuration =>
DependentMvvmInstanceConfiguration(
dependencies: [
app.connectors.postsInteractorConnector(),
],
);
late final postsInteractor = getLocalInstance<PostsInteractor>();
[@override](/user/override)
void onLaunch() {
postsInteractor.loadPosts(0, 30, refresh: true);
}
void openPost(Post post) {
// 了解更多关于导航组件的信息...
// app.navigation.routeTo(
// app.navigation.routes.post(
// post: post,
// ),
// forceGlobal: true,
// );
}
void like(int id) {
app.eventBus.send(PostLikedEvent(id: id));
}
Stream<StatefulData<List<Post>>?> get postsStream => postsInteractor.updates((state) => state.posts);
[@override](/user/override)
PostsListViewState get initialState => PostsListViewState();
}
class PostsListView extends BaseWidget {
const PostsListView({
super.key,
super.viewModel,
});
[@override](/user/override)
State<StatefulWidget> createState() {
return _PostsListViewWidgetState();
}
}
class _PostsListViewWidgetState extends BaseView<PostsListView, PostsListViewState, PostsListViewModel> {
[@override](/user/override)
Widget buildView(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromARGB(255, 232, 232, 232),
appBar: AppBar(title: const Text('Posts')),
body: StreamBuilder<StatefulData<List<Post>>?>(
stream: viewModel.postsStream,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data != null) {
return buildList(snapshot.data!);
}
return Container();
},
),
);
}
Widget buildList(StatefulData<List<Post>> data) {
switch (data) {
case LoadingData():
return const Center(child: CircularProgressIndicator());
case SuccessData<List<Post>>(:final result):
return ListView.builder(
itemBuilder: (context, index) {
final item = result[index];
return PostCard(
onTap: () {
viewModel.openPost(item);
},
onLikeTap: () {
viewModel.like(item.id ?? 1);
},
title: item.title ?? '',
body: item.body ?? '',
isLiked: item.isLiked,
);
},
itemCount: result.length,
);
case ErrorData<List<Post>>(:final error):
return Text(error.toString());
}
}
[@override](/user/override)
PostsListViewModel createViewModel() => PostsListViewModel();
}
更多关于Flutter MVVM架构插件umvvm的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter MVVM架构插件umvvm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于在Flutter项目中使用MVVM架构插件umvvm,以下是一个基本的代码示例,展示了如何设置和使用该插件来实现MVVM架构。假设你已经在pubspec.yaml文件中添加了umvvm依赖并运行了flutter pub get。
1. 添加依赖
首先,确保你的pubspec.yaml文件中包含以下依赖:
dependencies:
flutter:
sdk: flutter
umvvm: ^最新版本号 # 替换为实际最新版本号
2. 创建ViewModel
在你的项目中创建一个ViewModel类。这个类将包含业务逻辑和数据状态。
import 'package:umvvm/umvvm.dart';
class CounterViewModel extends BaseViewModel {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 通知视图更新
}
}
3. 创建View(Widget)
在你的lib目录下创建一个新的Dart文件,比如counter_view.dart,并在其中创建一个使用ViewModel的Widget。
import 'package:flutter/material.dart';
import 'package:umvvm/umvvm.dart';
import 'counter_view_model.dart'; // 假设你将ViewModel放在这个文件
class CounterView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ViewModelProvider<CounterViewModel>.withConsumer(
viewModel: CounterViewModel(),
builder: (context, viewModel, child) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter MVVM with umvvm'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${viewModel.count}',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
viewModel.increment();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
},
);
}
}
4. 使用View
在你的main.dart文件中使用这个CounterView。
import 'package:flutter/material.dart';
import 'counter_view.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CounterView(),
);
}
}
总结
以上代码展示了如何在Flutter项目中使用umvvm插件来实现MVVM架构。ViewModel负责业务逻辑和数据状态管理,而View(Widget)负责展示数据并响应用户交互。ViewModelProvider用于将ViewModel注入到View中,并通过notifyListeners方法通知视图更新。
请注意,这只是一个简单的示例。在实际项目中,你可能需要根据具体需求对ViewModel和View进行更复杂的实现,并可能需要处理更多的状态管理和依赖注入。

