Flutter如何将Future<void> fetchData()函数迁移到Service类适配MVVM架构
Flutter MVVM架构抽离接口请求实现方案
重构后项目分层结构
- lib/
- models/
- UserModel.dart // 现有用户数据模型
- services/
- user_service.dart // 抽离的独立接口请求服务层
- viewmodels/
- home_viewmodel.dart // MVVM业务逻辑层,管理页面状态
- pages/
- home_page.dart // UI层,仅负责视图渲染
- models/
步骤1:实现独立Service层(user_service.dart)
Service层仅负责处理接口请求、数据序列化,不耦合任何业务逻辑和UI状态:
import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:amaizi_test/models/UserModel.dart'; class UserService { final String _userApiUrl = 'https://jsonplaceholder.typicode.com/users'; final http.Client _httpClient = http.Client(); Future<List<UserModel>> fetchUserList() async { http.Response response = await _httpClient.get(Uri.parse(_userApiUrl)); if (response.statusCode == 200) { List responseJson = json.decode(response.body); return responseJson.map((item) => UserModel.fromJson(item)).toList(); } else { throw '接口请求错误'; } } }
步骤2:实现ViewModel层(home_viewmodel.dart)
ViewModel层承接UI层和数据层,管理页面状态、处理业务逻辑,使用ChangeNotifier实现状态通知:
import 'package:flutter/foundation.dart'; import 'package:amaizi_test/models/UserModel.dart'; import 'package:amaizi_test/services/user_service.dart'; class HomeViewModel extends ChangeNotifier { final UserService _userService = UserService(); bool _loading = true; List<UserModel> _userList = []; // 对外暴露只读状态 bool get loading => _loading; List<UserModel> get userList => _userList; Future<void> loadData() async { _loading = true; notifyListeners(); try { _userList = await _userService.fetchUserList(); } catch (e) { if (kDebugMode) { print('数据加载失败:$e'); } } finally { _loading = false; notifyListeners(); } } }
步骤3:改造HomePage页面
UI层仅监听状态变化渲染视图,在initState中触发数据加载:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:amaizi_test/viewmodels/home_viewmodel.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override void initState() { super.initState(); // 初始化调用数据加载 WidgetsBinding.instance.addPostFrameCallback((_) { Provider.of<HomeViewModel>(context, listen: false).loadData(); }); } @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => HomeViewModel(), child: Scaffold( appBar: AppBar(), body: Container( child: Consumer<HomeViewModel>( builder: (context, viewModel, child) { return viewModel.loading ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: viewModel.userList.length, itemBuilder: (BuildContext context, int index) { return Card( child: ListTile( title: Text(viewModel.userList[index].name), ), ); }, ); }, ), ), ), ); } }
依赖配置说明
需要在pubspec.yaml中添加对应依赖:
dependencies: flutter: sdk: flutter provider: ^6.1.1 # 状态管理依赖 http: ^1.1.0 # 网络请求依赖
内容的提问来源于stack exchange,提问作者Clinton
相关产品推荐
相关产品推荐

