【FlutterDart】MVVM(Model-View-ViewModel)架构模式例子-http版本(30 /100)
动图更精彩
MVVM(Model-View-ViewModel)
特点
Model:负责数据管理和业务逻辑。
View:负责显示数据,通常是一个UI组件。
ViewModel:负责处理用户交互,更新Model,并将数据转换为View可以显示的格式。
适用场景
大型项目:适合大型项目,因为ViewModel可以很好地管理视图和模型之间的交互。
需要高可维护性和可扩展性的项目:ViewModel可以独立于View进行单元测试,提高代码的可维护性和可扩展性。
优缺点
优点:
ViewModel可以独立于View进行单元测试,提高测试覆盖率。
适合大型项目,结构清晰,易于维护和扩展。
与Flutter的StatefulWidget和StatelessWidget结合得很好。
缺点:
需要更多的代码来定义ViewModel和数据绑定。
代码结构相对复杂,新手上手可能需要一些时间。
推荐架构:MVVM
结构比起mvc的确难了不少,不过本就是中大型项目。只能硬头皮上了。
也不一定非要说mvvm。mvc,mvp等等按实际需要进行实际使用即可。不过练手用mvvm会提高熟悉度。
代码如下:
model 也放一起了,其实没有用到,只是为了符合结构。
ViewModel 如下:
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:logger/logger.dart';
class ResponseResult {
late int code;
late String data;
ResponseResult({required this.code, required this.data});
factory ResponseResult.fromJson(Map<String, dynamic> json) {
return ResponseResult(
code: json['code'],
data: json['data'],
);
}
}
class ApiModel extends ChangeNotifier {
ResponseResult? _responseResult;
ResponseResult? get responseResult => _responseResult;
bool _isLoading = false;
bool get isLoading => _isLoading;
String _result = '';
String get result => _result;
Future<void> fetchHttp() async {
_isLoading = true;
notifyListeners();
var url = 'https://api.apiopen.top/api/sentences';
// url = 'https://cn.bing.com/';
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
_result = response.body;
} else {
throw Exception('Failed to load user');
}
_isLoading = false;
notifyListeners();
}
}
view 如下:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smart_api/smartApi/model/api_model.dart';
class ApiDemo extends StatelessWidget {
const ApiDemo({super.key});
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ApiModel(),
child: ApiView(),
);
}
}
class ApiView extends StatelessWidget {
const ApiView({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ApiView'),
),
body: Consumer<ApiModel>(builder: (context, viewModel, child) {
if (viewModel.isLoading) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Text(viewModel.result);
}
}),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<ApiModel>().fetchHttp();
},
child: Icon(Icons.send),
),
);
}
}
刚开始使用,的确不太友好,很多业务逻辑都不是很清晰,还需要再拆细致一些才能刚好理解
SmartApi开始折腾业务数据了,离原型版本又近一步了…