当前位置: 首页 > news >正文

React:Umi + React + Ant Design Pro的基础上接入Mock数据

为什么需要Mock数据

前端开发依赖后端接口时的阻塞问题
独立开发和测试的需求
快速迭代和原型验证的重要性

当前版本及框架

React18
Umi 4.0
Ant Design + Ant Design Pro

其实这些都不重要,主要是有Umijs,因为Umijs具有开箱即用Mock功能的能力,可参考官网文档:UmiJS-Mock

实践

前提

如果你想使用Umi里面的mock,那么必须安装Umi框架,用npm或者pnpm就正常安装,此步骤不在赘述,以下直接实践

第一步 创建一个mock文件

在这里插入图片描述
不用纠结这个 文件是放在src下面,还是谁的下面,直接就这个项目里面,与src平级关系

第二步 在mock创建对应的ts文件,放置模拟数据和接口

mock/ip.ts

const MOCK_DATA = [{id: '1',used: 10,total: 14,region: '洛杉矶',coreRoute: 'US',exitNode: 'Uplink',remark: 'TikTok直播专用',},{id: '2',used: 13,total: 14,region: '洛杉矶',coreRoute: 'US',exitNode: 'Uplink',remark: 'TikTok直播专用',},{id: '3',used: 0,total: 14,region: '洛杉矶',coreRoute: 'US',exitNode: 'Uplink',remark: 'Amazon电商专用',}
];// 抽屉列表的专用数据源(按段 id 区分)
const IP_PERMISSION_DATA: Record<string, any[]> = {
……// 数组包裹数组
};export default {// 列表(保留)'POST /api/ip/list': (req: any, res: any) => {setTimeout(() => {res.send({ success: true, data: MOCK_DATA, total: MOCK_DATA.length });}, 120);},// 获取单条详情:根据 body.id 返回对应 record'POST /api/ip/detail': (req: any, res: any) => {const { id } = req.body || {};const item = MOCK_DATA.find((it) => String(it.id) === String(id));setTimeout(() => {res.send({ success: true, data: item || null });}, 80);},// 更新(简单模拟,body 包含 id 与其他字段)'POST /api/ip/update': (req: any, res: any) => {const payload = req.body || {};const idx = MOCK_DATA.findIndex((it) => String(it.id) === String(payload.id));if (idx >= 0) {MOCK_DATA[idx] = { ...MOCK_DATA[idx], ...payload };}setTimeout(() => {res.send({ success: true, message: '更新成功(mock)', data: MOCK_DATA[idx] || null });}, 120);},// 权限管理抽屉列表'POST /api/ip/children': (req: any, res: any) => {const { id, cidr } = req.body || {};let key = id ? String(id) : undefined;if (!key && cidr) {const found = MOCK_DATA.find((it) => String(it.cidr) === String(cidr));key = found?.id;}const data = (key && IP_PERMISSION_DATA[key]) || [];setTimeout(() => res.send({ success: true, data, total: data.length }), 100);},
};

第三步 调用mock数据和接口

放在某个调用接口的.tsx文件里面

  // 列表数据(来自 /mock/ip.ts)const [ipList, setIpList] = useState<any[]>([]);// 加载列表(调用 mock 的 GET /api/ip/list,后端到位时直接替换)const loadIpList = useCallback(async (opts?: { page?: number; pageSize?: number }) => {const page = opts?.page || currentPage;const size = opts?.pageSize || pageSize;const payload = {page,pageSize: size,keyword: keyWord || '',source: filterSource || '',coreRoute: filterCoreRoute || '',};try {const res = await fetch('/api/ip/list', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify(payload),});// 期望后端/Mock 返回 JSON 格式 { success: true, data: [...], total: n }const ct = (res.headers.get('content-type') || '').toLowerCase();if (!ct.includes('application/json')) {console.warn('loadIpList non-json response');setIpList([]);setTotal(0);return;}const json = await res.json();if (json && json.success) {setIpList(json.data || []);setTotal(json.total || 0);} else if (json && Array.isArray(json.data)) {// 兜底兼容setIpList(json.data || []);setTotal(json.total || json.data.length || 0);} else {setIpList([]);setTotal(0);}} catch (err) {console.error('loadIpList error', err);setIpList([]);setTotal(0);}},[currentPage, pageSize, keyWord, filterSource, filterCoreRoute],);// 获取单条详情(调用 mock 的 POST /api/ip/detail)const getIpDetail = useCallback(async (id: string | number) => {try {const res = await fetch('/api/ip/detail', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ id }),});const json = await res.json();if (json && json.success) return json.data;return null;} catch (err) {console.error('getIpDetail error', err);return null;}}, []);// 更新 IP 段(调用 mock 的 POST /api/ip/update),成功后刷新列表const updateIp = useCallback(async (payload: any) => {try {const res = await fetch('/api/ip/update', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify(payload),});const json = await res.json();if (json && json.success) {// 刷新当前页loadIpList({ page: currentPage, pageSize });return { ok: true, data: json.data };}return { ok: false, error: json };} catch (err) {console.error('updateIp error', err);return { ok: false, error: err };}},[loadIpList, currentPage, pageSize],);
// 比如这个列表接口调用
useEffect(() => {loadIpList();
}, [currentPage, pageSize, filterSource, filterRegion, keyWord]);

在这里插入图片描述

第四步 注意是否开启mock

以我此刻的项目为例,
npm run start
在这里插入图片描述

http://www.dtcms.com/a/342236.html

相关文章:

  • nuxt3 404页面 如何写
  • 当云手机进入不了游戏怎么办?
  • 1504. 统计全 1 子矩形
  • windows中bat脚本中一些操作(一)
  • 关于 VScode 无法连接 Linux 主机并报错 <未能下载 VScode 服务器> 的解决方案
  • 强化学习算法分类与介绍(含权重更新公式)
  • 从vue2到vue3
  • VASPKIT模版INCAR笔记
  • K8s快速上手-微服务篇篇
  • 【ZeroNews】OpenWrt路由器小存储开启内网穿透
  • 2025年8月新算法—云漂移优化算法(Cloud Drift Optimization Algorithm, CDO)
  • C++ this 指针
  • 2025-08-21 Python进阶2——数据结构
  • Rancher部署的K8S集群服务节点上执行 kubectl 命令
  • JavaCV + Spring 实现高效 RTSP 视频流帧缓存与管理
  • MybatisPlusAutoConfiguration源码阅读
  • 稀土元素带来农业科技革命
  • Qt5 数据库编程详解
  • “Data + AI Agent”技术架构解析:衡石科技如何重塑数据智能演进路径?
  • YggJS RToast(科技风全局消息通知库) 使用教程 v0.1.0(详细教学)
  • RoPE, 2D RoPE, 3D RoPE和复数
  • 安卓app、微信小程序等访问多个api时等待提示调用与关闭问题
  • 为什么会“偶发 539/500 与建连失败”
  • 如何通过传感器选型优化,为设备寿命 “续航”?
  • 微服务介绍及Nacos中间件
  • java⽇志体系
  • 桌面挂件不能承受之重——GIF
  • Windows 系统中,添加打印机主要有以下几种方式
  • 聚铭安全管家平台2.0实战解码 | 安服篇(四):重构威胁追溯体系
  • 新手向:Python开发简易网络服务器