You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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层,仅负责视图渲染

步骤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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:48:03