flutter实现Mock数据

在Flutter中,mock_http_server 用于启动本地 HTTP 服务器,模拟真实接口服务(支持 GET/POST/DELETE 等方法),适合开发阶段直接请求本地 Mock 接口。

添加依赖

pubspec.yaml 中添加所需依赖:

yaml

yaml 复制代码
dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.3+1          # 网络请求库(用于请求Mock服务器)
  json_annotation: ^4.9.0 # JSON序列化

dev_dependencies:
  flutter_test:
    sdk: flutter

  mock_http_server: ^1.0.0 # 本地Mock HTTP服务器
  json_serializable: ^6.7.1 # JSON序列化生成

执行 flutter pub get 安装依赖。

步骤 1:启动 Mock HTTP 服务器

创建 lib/mock/mock_server.dart

dart 复制代码
import 'dart:convert';
import 'package:mock_http_server/mock_http_server.dart';

class MockHttpServerManager {
  late MockHttpServer _server;
  int port = 8080; // 本地Mock服务器端口

  // 启动Mock服务器
  Future<void> start() async {
    _server = MockHttpServer();
    await _server.start(port); // 启动服务器
    _configureRoutes(); // 配置接口路由
    print('Mock HTTP Server started on http://localhost:$port');
  }

  // 停止Mock服务器
  Future<void> stop() async {
    await _server.stop();
    print('Mock HTTP Server stopped');
  }

  // 配置Mock接口路由
  void _configureRoutes() {
    // 1. 模拟商品列表GET接口
    _server.when('/goods/list', method: 'GET').thenReply((request) {
      // 获取请求参数(如page/size)
      final queryParams = request.uri.queryParameters;
      final page = int.parse(queryParams['page'] ?? '1');
      final size = int.parse(queryParams['size'] ?? '10');

      // 模拟动态返回数据(根据参数)
      final mockData = {
        "code": 200,
        "data": List.generate(size, (index) => {
          "id": "${page}_$index",
          "title": "Mock商品$page-$index",
          "price": "¥${100 + index}",
          "location": "北京朝阳",
          "time": "1小时前"
        })
      };

      return MockHttpResponse(
        body: json.encode(mockData),
        statusCode: 200,
        headers: {'Content-Type': 'application/json'},
      );
    });

    // 2. 模拟删除商品DELETE接口(成功场景)
    _server.when(RegExp(r'/goods/\d+'), method: 'DELETE').thenReply((request) {
      final goodsId = request.uri.path.split('/').last;
      return MockHttpResponse(
        body: json.encode({
          "code": 200,
          "msg": "商品$goodsId删除成功"
        }),
        statusCode: 200,
      );
    });

    // 3. 模拟异常接口(500错误)
    _server.when('/goods/error', method: 'GET').thenReply((request) {
      return MockHttpResponse(
        body: json.encode({
          "code": 500,
          "msg": "服务器内部错误"
        }),
        statusCode: 500,
      );
    });
  }
}

步骤 2:在项目中使用 Mock 服务器

修改 lib/main.dart,启动 Mock 服务器并请求接口:

dart 复制代码
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'mock/mock_server.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 1. 启动Mock HTTP服务器
  final mockServer = MockHttpServerManager();
  await mockServer.start();

  // 2. 初始化Dio,请求本地Mock服务器
  final dio = Dio();
  dio.options.baseUrl = 'http://localhost:8080';

  runApp(MyApp(dio: dio, mockServer: mockServer));
}

class MyApp extends StatelessWidget {
  final Dio dio;
  final MockHttpServerManager mockServer;

  const MyApp({super.key, required this.dio, required this.mockServer});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Mock HTTP Server Demo',
      home: Scaffold(
        appBar: AppBar(title: const Text('Mock HTTP Demo')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // 请求商品列表接口
              ElevatedButton(
                onPressed: () async {
                  try {
                    final response = await dio.get('/goods/list', queryParameters: {
                      'page': 1,
                      'size': 5
                    });
                    print('商品列表:${response.data}');
                  } catch (e) {
                    print('请求失败:$e');
                  }
                },
                child: const Text('请求Mock商品列表'),
              ),
              // 请求错误接口
              ElevatedButton(
                onPressed: () async {
                  try {
                    final response = await dio.get('/goods/error');
                    print('错误接口响应:${response.data}');
                  } catch (e) {
                    print('错误接口请求失败:$e');
                  }
                },
                child: const Text('请求错误接口'),
              ),
              // 删除商品接口
              ElevatedButton(
                onPressed: () async {
                  try {
                    final response = await dio.delete('/goods/123');
                    print('删除商品:${response.data}');
                  } catch (e) {
                    print('删除失败:$e');
                  }
                },
                child: const Text('删除Mock商品'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

步骤 3:运行效果

  1. 启动项目后,控制台会输出 Mock HTTP Server started on http://localhost:8080
  2. 点击「请求 Mock 商品列表」,控制台会打印动态生成的商品数据(根据 page/size 参数);
  3. 点击「请求错误接口」,会捕获 500 错误;
  4. 点击「删除 Mock 商品」,会返回删除成功的响应。

核心知识点总结

特性 实现方式
匹配固定路径 _server.when('/goods/list', method: 'GET')
匹配正则路径 _server.when(RegExp(r'/goods/\d+'), method: 'DELETE')
动态返回数据 根据 request.uri.queryParameters 生成不同响应
模拟错误状态码 MockHttpResponse(statusCode: 500, ...)
相关推荐
CC码码1 小时前
前端文本分割工具,“他”来了
前端·javascript·程序员
Keely402851 小时前
浏览器指纹识别:从原理到防护的完整指南
前端·浏览器
沐道PHP1 小时前
nvm安装node低版本失败-解决方案
前端
韩曙亮1 小时前
【Web APIs】JavaScript 执行机制 ( 单线程特点 | 同步任务与异步任务 | 同步先行、异步排队 | 事件循环机制 )
开发语言·前端·javascript·异步任务·同步任务·web apis·js 引擎
linhuai1 小时前
Flutter如何实现头部固定
前端
单调7771 小时前
npm你还了解多少
前端
码途进化论1 小时前
基于 Vue 2 + VXE Table 的超大规模表格渲染架构设计与性能优化方案
前端
漫天星梦1 小时前
iOS 手机无法播放视频问题排查与解决方案记录
前端·ios
好好好明天会更好1 小时前
uniapp项目中视频播放控制对象
前端·vue.js