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, ...)
相关推荐
敲敲了个代码15 小时前
从硬编码到 Schema 推断:前端表单开发的工程化转型
前端·javascript·vue.js·学习·面试·职场和发展·前端框架
dly_blog16 小时前
Vue 响应式陷阱与解决方案(第19节)
前端·javascript·vue.js
消失的旧时光-194316 小时前
401 自动刷新 Token 的完整架构设计(Dio 实战版)
开发语言·前端·javascript
console.log('npc')17 小时前
Table,vue3在父组件调用子组件columns列的方法展示弹窗文件预览效果
前端·javascript·vue.js
用户479492835691517 小时前
React Hooks 的“天条”:为啥绝对不能写在 if 语句里?
前端·react.js
我命由我1234517 小时前
SVG - SVG 引入(SVG 概述、SVG 基本使用、SVG 使用 CSS、SVG 使用 JavaScript、SVG 实例实操)
开发语言·前端·javascript·css·学习·ecmascript·学习方法
用户479492835691518 小时前
给客户做私有化部署,我是如何优雅搞定 NPM 依赖管理的?
前端·后端·程序员
C_心欲无痕18 小时前
vue3 - markRaw标记为非响应式对象
前端·javascript·vue.js
qingyun98918 小时前
深度优先遍历:JavaScript递归查找树形数据结构中的节点标签
前端·javascript·数据结构
熬夜敲代码的小N18 小时前
Vue (Official)重磅更新!Vue Language Tools 3.2功能一览!
前端·javascript·vue.js