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

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.xdnf.cn/news/18520.html

相关文章:

  • Unity编辑器相关
  • 基于STM32设计的大棚育苗管理系统(4G+华为云IOT)_265
  • RabbitMQ:技巧汇总
  • 如何用 SolveigMM Video Splitter 从视频中提取 AAC 音频
  • leetcode_238 除自身以外的数组乘积
  • 实践题:智能客服机器人设计
  • 【Dify(v1.x) 核心源码深入解析】prompt 模块
  • centos下安装Nginx(搭建高可用集群)
  • 利用随机森林筛查 “癌症点”
  • yggjs_react使用教程 v0.1.1
  • Excel中运行VB的函数
  • 自然处理语言NLP:One-Hot编码、TF-IDF、词向量、NLP特征输入、EmbeddingLayer实现、word2vec
  • Docker安装elasticsearch以及Kibana、ik分词器
  • Day24 目录遍历、双向链表、栈
  • k8s集合
  • GIS在城乡供水一体化中的应用
  • CT02-20.有效的括号(Java)
  • Flutter 线程模型详解:主线程、异步与 Isolate
  • 机器学习中的两大核心算法:k 均值聚类与集成学习
  • Linux之Ansible自动化运维(二)
  • 分布式集群压测+grafana+influxdb+Prometheus详细步骤
  • 小程序个人信息安全检测技术:从监管视角看加密与传输合规
  • 【StarRocks】-- SQL CTE 语法
  • Ubuntu22.04安装VMware Tools
  • STM32H750 CoreMark跑分测试
  • Chrome/360 浏览器 WebUI 资源底层机制解析:共享资源与专属资源的奥秘
  • Web自动化测试:测试用例流程设计
  • 如何处理项目中棘手的依赖版本冲突问题
  • Eino 框架组件协作指南 - 以“智能图书馆建设手册”方式理解
  • PHP:历经岁月仍熠熠生辉的服务器端脚本语言