React 全栈开发中,Mock 如何让前后端协作如丝般顺滑?

做全栈开发的小伙伴可能都有过这种经历:前端页面搭好了大半,后端接口还在排期;好不容易等后端接口上线,联调时发现数据格式和预期差了十万八千里。这种 "前后端不同步" 的痛,在 React 项目里尤其明显 ------ 组件状态、数据流都搭好了,就差数据来驱动,只能对着空页面发呆。

但自从我在项目里用了 Mock,这种尴尬局面就再也没出现过。今天跟大家聊聊 Mock 到底怎么玩才能让前后端协作效率翻倍。

为什么 React 项目更需要 Mock?

React 项目的组件化开发模式,决定了我们经常需要基于数据结构设计组件。比如一个 TodoList 组件,得知道每条 todo 的 id、title、completed 这些字段才能动手。但现实往往是:产品经理催着出原型,后端说 "接口下周才能好"。

这时候 Mock 就成了救星 ------ 它能帮我们在没有后端接口的情况下,先定义好数据格式,让组件开发、状态管理、交互逻辑都能正常推进。等后端接口 ready 后,只需要切换一下数据源,整个流程无缝衔接。

就像我最近做的表演型项目,前端用 React,后端计划用 Node.js。立项会上定好接口文档后,我当天就用 Mock 把所有接口模拟出来了,等后端一周后完成接口开发时,我的前端页面已经能完美运行,联调只用了半天就搞定。

在 React+Vite 项目中配置 Mock

既然是 Vite+React 项目,那 vite-plugin-mock 肯定是首选方案,配置起来比传统方式简单太多。

首先安装依赖:

bash 复制代码
npm install mockjs vite-plugin-mock --save-dev

然后在 vite.config.js 里配置插件:

js 复制代码
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { viteMockServe } from 'vite-plugin-mock'
export default defineConfig({
  plugins: [
    react(),
    viteMockServe({
      mockPath: './mock', // 存放mock文件的目录
      localEnabled: true, // 开发环境启用mock
      prodEnabled: false, // 生产环境关闭mock
      supportTs: false // 是否支持TypeScript
    })
  ]
})

接着在项目根目录创建 mock 文件夹,新建 test.js 文件:

js 复制代码
// mock/test.js
export default [
  {
    url: '/api/todos', 
    method: 'get', 
    response: () => {
      // 模拟返回数据
      return {
        code: 0,
        message: 'success',
        data: [
          { id: 1, title: '完成Mock配置', completed: true },
          { id: 2, title: '开发Todo组件', completed: false }
        ]
      }
    }
  }
]

启动项目后,访问http://localhost:5173/api/todos,就能看到模拟的数据了。这时候在 React 组件里用 axios 请求这个接口,完全和真实接口一样:

jsx 复制代码
import { useEffect, useState } from 'react';
import axios from 'axios';
function TodoList() {
  const [todos, setTodos] = useState([]);
  useEffect(() => {
    axios.get('/api/todos').then(res => {
      setTodos(res.data.data);
    });
  }, []);
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id} style={{ textDecoration: todo.completed? 'line-through' : 'none' }}>
          {todo.title}
        </li>
      ))}
    </ul>
  );
}

这段代码写完,就算后端还没开始动工,我们的 TodoList 已经能正常展示数据了。

Mock 进阶技巧

基础配置很简单,但要让 Mock 真正发挥作用,还得掌握这些实用技巧。

1.数据模板定义和占位符

Mock.js 最强大的地方就是它的数据模板定义,掌握了这个,你就能生成各种想要的数据。

基本语法是'属性名|生成规则': 属性值。 比如,我们需要模拟一个获取用户列表的接口,并且列表中的数据是随机生成的。我们可以这样编写 Mock 文件:

js 复制代码
import Mock from 'mockjs'; 

export default [
  {
    url: '/api/users',
    method: 'get',
    response: () => {
      const users = Mock.mock({
        'list|5-10': [
          {
            'id|+1': 1,
            'name': '@cname',
            'age|18-60': 1,
            'email': '@email',
            'date': '@date(yyyy-MM-dd)', 
            'image': '@image(200x100)', 
            'paragraph': '@cparagraph(3, 5)' 
          },
        ],
      });

      return {
        code: 0,
        message: 'success',
        data: users.list,
      };
    },
  },
];

在这段代码中,我们使用了 Mock.js 的强大语法来生成随机数据。'list|5-10' 表示生成一个包含 5 到 10 个元素的数组,每个元素都是一个用户对象。'id|+1': 1 表示 id 从 1 开始自增,'name': '@cname' 表示生成一个随机的中文名,'age|18-60': 1 表示生成一个 18 到 60 之间的随机年龄,'email': '@email' 表示生成一个随机的邮箱地址,'date': '@date(yyyy-MM-dd)' 表示生成'yyyy-MM-dd'格式的日期, 'image': '@image(200x100)' 表示生成一张200*100的图片, 'paragraph': '@cparagraph(3, 5)'表示生成3-5段中文段落 。

这样,当我们前端发起 /api/users 的请求时,Mock.js 会返回一个包含随机用户信息的列表,满足我们更复杂的业务需求。

2. 动态返回数据

真实接口往往会根据请求参数返回不同数据。比如获取单个 todo 详情的接口,需要根据 id 返回对应数据:

js 复制代码
// mock/todo.js
export default [
  {
    url: '/api/todos/:id', // 带参数的接口
    method: 'get',
    response: (req) => {
      const { id } = req.params; // 获取url参数
      // 模拟数据库查询
      const todoList = [
        { id: 1, title: '学习Mock', completed: false },
        { id: 2, title: '开发组件', completed: true }
      ];
      const target = todoList.find(item => item.id === Number(id));
      
      return {
        code: target? 0 : 404,
        message: target? 'success' : '未找到该todo',
        data: target || null
      };
    }
  }
]

3. 处理不同请求类型

实际开发中接口请求类型多样,除了常见的 GET,还有 POST、PUT、DELETE 等,Mock 都能妥善处理。比如处理 POST 请求:

js 复制代码
// mock/todo.js 新增POST接口
{
  url: '/api/todos',
  method: 'post',
  response: (req) => {
    const { title } = req.body; // 获取请求体数据
    if (!title) {
      return { code: 1, message: '标题不能为空', data: null };
    }
    // 模拟新增数据
    return {
      code: 0,
      message: '添加成功',
      data: { id: Date.now(), title, completed: false }
    };
  }
}

在 React 组件里调用时和真实接口完全一样:

jsx 复制代码
const addTodo = async (title) => {
  try {
    const res = await axios.post('/api/todos', { title });
    if (res.data.code === 0) {
      setTodos(prevTodos => [...prevTodos, res.data.data]); 
    }
  } catch (error) {
    console.error('添加失败:', error);
  }
};

4. 模拟加载状态

真实网络请求有延迟,我们可以在 Mock 里设置响应时间,测试加载状态:

js 复制代码
// 在vite.config.js中配置全局延迟
viteMockServe({
  // 其他配置...
  delay: 500 // 所有接口延迟500ms返回
})

这样就能在组件里测试 loading 状态的展示效果,让用户体验更贴近真实场景。

5.区分环境使用

在实际项目中,我们通常希望开发环境使用 Mock 数据,生产环境则调用真实接口。可以通过环境变量来控制:

js 复制代码
// 在mock/index.js中
if (process.env.NODE_ENV === 'development') {
  // 只在开发环境加载Mock配置
  import './user.js';
  import './goods.js';
}

然后在 package.json 的 scripts 中配置环境变量:

json 复制代码
"scripts": {
  "start": "REACT_APP_ENV=development react-scripts start",
  "build": "REACT_APP_ENV=production react-scripts build"
}

6.Mock 与 React 状态管理结合

在使用 Redux、MobX 等状态管理库的 React 项目中,Mock 数据也能无缝融入。以 Redux 为例,异步 action 获取 Mock 数据的方式和真实接口一致:

js 复制代码
// actions/userActions.js
import axios from 'axios';
export const fetchUser = (id) => {
  return async (dispatch) => {
    dispatch({ type: 'FETCH_USER_START' });
    try {
      const res = await axios.get(`/api/user?id=${id}`);
      dispatch({
        type: 'FETCH_USER_SUCCESS',
        payload: res.data.data
      });
    } catch (err) {
      dispatch({
        type: 'FETCH_USER_ERROR',
        payload: err.message
      });
    }
  };
};

组件中调用 action 的代码完全不用考虑数据来源是 Mock 还是真实接口,这种一致性让状态管理逻辑更纯粹。

前后端联调

当后端接口开发完成后,我们需要进行前后端联调。此时,我们只需要将 vite.config.js 中的 prodEnabled 设置为 false,关闭 Mock.js 的功能,前端请求就会直接发送到后端真实接口。在联调过程中,如果发现数据格式不一致等问题,我们可以及时与后端沟通调整,确保项目的顺利进行。

总结

用好Mock 让前端开发从 "被动等待" 变成 "主动推进"。尤其是在 React 项目中,提前用 Mock 定义好数据结构,能让组件设计更合理,状态管理更清晰。

你们项目里有什么 Mock 的骚操作?欢迎在评论区分享,让我也取取经~

相关推荐
G_G#7 分钟前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
@大迁世界23 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路32 分钟前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug35 分钟前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu1213837 分钟前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中1 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 小时前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架
前端 贾公子1 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端
菩提小狗2 小时前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全