使用 Mock.js 模拟 API 数据,实现前后端并行开发

使用 Mock.js 模拟 API 数据,实现前后端并行开发

引言

在现代前端开发中,前后端分离已经成为标配。后端负责提供 API 接口,前端负责页面和交互。然而,在项目初期,后端接口往往还未就绪,前端开发不能因此阻塞。这时,我们可以在前端自己模拟(Mock)数据,让开发能够并行推进。Mock.js 就是一个非常实用的工具,它能帮助我们快速生成随机数据,并拦截 Ajax 请求,返回模拟的响应数据。

本文将以一个真实的代码示例(模拟文章列表接口)为线索,带你逐步掌握 Mock.js 的核心用法,并实现一个带有分页功能的模拟接口。


1. 为什么需要 Mock 数据?

  • 前后端并行开发:前端不依赖后端接口进度,可独立开发和调试。
  • 接口文档先行:前后端可以事先约定好接口数据结构,前端根据文档模拟数据,后端按照文档实现。
  • 测试场景覆盖:轻松生成大量随机数据,方便测试列表、分页、异常情况等。
  • 演示与原型:快速搭建可交互的原型,用于展示或评审。

2. 快速上手 Mock.js

2.1 安装

在项目中使用 npm 或 yarn 安装:

bash 复制代码
npm install mockjs --save-dev
# 或
yarn add mockjs --dev

2.2 基本用法

Mock.js 提供了 Mock.mock() 方法,可以根据数据模板生成随机数据:

javascript 复制代码
import Mock from 'mockjs'

const data = Mock.mock({
  'list|5': [{
    'id|+1': 1,
    'name': '@cname'
  }]
})
console.log(data)
// 输出:{ list: [ { id: 1, name: '张三' }, ... ] }
  • 'list|5' 表示生成一个数组,长度为 5。
  • 'id|+1' 表示 id 每次自增 1。
  • '@cname' 是 Mock.js 内置的随机中文名。

有了初步印象后,我们开始构建一个更真实的场景。


3. Mock.js 语法详解:构建文章列表数据

假设我们需要模拟一个博客文章列表,每篇文章包含标题、简介、评论数、点赞数、发布时间、作者信息、标签、缩略图、图片列表以及唯一 ID。下面是完整的模拟数据生成代码(参考你提供的 posts.js):

javascript 复制代码
import Mock from 'mockjs'

// 可选的标签列表
const tags = ['前端', '后端', '职场', 'AI', '副业', '面经', '算法']

const posts = Mock.mock({
  // 生成 45 条文章数据
  'list|45': [
    {
      title: '@ctitle(8,20)',                 // 随机中文标题,8-20个字符
      brief: '@ctitle(20,100)',                // 随机简介,20-100个字符
      totalComment: '@integer(1,30)',           // 评论数 1-30
      totalLikes: '@integer(0,500)',            // 点赞数 0-500
      publishedAt: '@datetime("yyyy-MM-dd HH:mm:ss")', // 随机时间

      // 嵌套的作者信息
      user: {
        id: '@integer(1,10)',                    // 用户ID 1-10
        name: '@cname(2,4)',                      // 用户名 2-4个中文字符
        avatar: '@image("300x200")',               // 随机图片作为头像
      },

      // 标签:随机选取 2 个不同的标签
      tags: () => Mock.Random.shuffle(tags).slice(0, 2),

      thumbnail: '@image("300x200")',              // 缩略图
      pics: [                                       // 图片列表
        '@image("300x200")',
        '@image("300x200")',
        '@image("300x200")',
      ],

      id: '@increment(1)',                         // 自增 ID,从 1 开始
    },
  ],
}).list

export default posts

3.1 常用占位符说明

占位符 说明 示例输出
@ctitle(min, max) 随机中文标题 "深入浅出前端工程化"
@integer(min, max) 随机整数 27
@datetime(format) 随机日期时间 "2023-08-15 14:23:09"
@cname(min, max) 随机中文名字 "李小明"
@image(size) 随机图片占位(需网络请求) "dummyimage.com/300x200"
@increment(step) 自增,step 为步长 1,2,3...
() => Mock.Random.shuffle() 自定义函数处理标签随机选取

⚠️ 注意Mock.Random.pick(array) 只能随机选取一个元素。要选取多个不同标签,可以像上面那样先 shuffleslice


4. 模拟接口并实现分页

有了模拟数据后,下一步是拦截 Ajax 请求,返回分页后的数据。通常我们会创建一个 mock 文件夹,里面定义各个接口的响应逻辑。下面是模拟 /api/posts 接口的完整代码:

javascript 复制代码
// mock/posts.js
import posts from './data/posts'   // 上一步生成的 45 条文章数据

export default [
  {
    url: '/api/posts',          // 接口地址
    method: 'get',               // 请求方法
    response: ({ query }, res) => {
      console.log(query, '//////')

      // 1. 获取分页参数,并设置默认值
      const { page = '1', limit = '10' } = query
      const currentPage = parseInt(page, 10)
      const size = parseInt(limit, 10)

      // 2. 参数校验
      if (isNaN(currentPage) || isNaN(size) || currentPage < 1 || size < 1) {
        return {
          code: 400,
          msg: 'Invalid page or pageSize',
          data: null,
        }
      }

      // 3. 计算切片范围
      const total = posts.length
      const start = (currentPage - 1) * size
      const end = start + size
      const pageinatedData = posts.slice(start, end)

      // 4. 返回成功响应
      return {
        code: 200,
        msg: 'success',
        data: pageinatedData,
        pagination: {
          current: currentPage,
          limit: size,
          total,
          totalPage: Math.ceil(total / size),
        },
      }
    },
  },
]

4.1 代码解读

  • 参数解析 :从 query 对象中获取 pagelimit,并转换为数字类型。
  • 边界处理 :若参数无效,返回 400 错误码。
  • 数据切片 :利用数组的 slice 方法取出当前页的数据。
  • 分页元数据 :返回 pagination 对象,包含当前页、每页条数、总条数和总页数,方便前端渲染分页组件。

4.2 如何在项目中使用?

在实际项目中,你可以通过以下方式启用这些 Mock 接口:

  • 使用 vite-plugin-mock:在 Vite 项目中配置插件,将上述数组传入即可自动拦截对应请求。
  • 使用 webpack-dev-serverbefore 钩子 :在 devServer.before 中注册中间件。
  • 使用 Mock.mock 拦截 XHR :Mock.js 本身可以拦截浏览器发出的 Ajax 请求,语法为 Mock.mock(url, method, responseFn)。不过需要注意,这种方式会拦截所有符合规则的请求,适用于纯前端项目。

例如,用 Mock.js 原生拦截:

javascript 复制代码
import Mock from 'mockjs'
import posts from './data/posts'

Mock.mock('/api/posts', 'get', (options) => {
  // options 包含 url, type, body 等信息
  const url = new URL(options.url, location.origin)
  const page = url.searchParams.get('page') || '1'
  const limit = url.searchParams.get('limit') || '10'
  // ... 同上处理逻辑
})

5. 扩展:根据查询参数动态过滤数据

除了分页,实际接口往往还需要支持关键词搜索、标签筛选等功能。我们可以在 response 函数中进一步处理查询参数,动态过滤数据。

例如,增加按标题关键词搜索:

javascript 复制代码
response: ({ query }) => {
  const { page = '1', limit = '10', keyword = '' } = query
  // ... 解析参数、校验

  // 先过滤:如果有关键词,只保留标题包含关键词的文章
  let filteredPosts = posts
  if (keyword) {
    filteredPosts = posts.filter(item => item.title.includes(keyword))
  }

  const total = filteredPosts.length
  const start = (currentPage - 1) * size
  const end = start + size
  const pageinatedData = filteredPosts.slice(start, end)

  return {
    code: 200,
    msg: 'success',
    data: pageinatedData,
    pagination: {
      current: currentPage,
      limit: size,
      total,
      totalPage: Math.ceil(total / size),
    },
  }
}

类似地,你还可以增加按标签筛选、按时间排序等功能,使得模拟接口更加贴近真实场景。


6. 结语

Mock.js 是一个非常轻量且强大的工具,它能帮助前端开发者在后端接口就绪前独立完成开发任务。通过本文的学习,你应该已经掌握了:

  • Mock.js 的基本语法和常用占位符
  • 如何生成复杂的嵌套数据
  • 如何编写带分页功能的模拟接口
  • 如何扩展过滤和搜索逻辑

当后端接口开发完成后,你只需要将 Mock 的接口定义注释掉,或者通过环境变量切换,就能无缝接入真实数据。这种模式不仅能提升开发效率,还能让团队协作更加顺畅。

希望本文能对你有所帮助,如果你在实践中有任何问题或心得,欢迎在评论区交流讨论!

相关推荐
琛説2 小时前
Web-Rooter:一种 IR + Lint 模式的 AI Agent 创新尝试【或许是下一个 AI 爆火方向】
前端·人工智能
向上的车轮2 小时前
TypeScript 一日速通指南:数据类型全解析与转换指南
javascript·typescript
用户9714171814272 小时前
absolute 元素的包含块(containing block)怎么找
前端·css
青山Coding2 小时前
Cesium应用(四):全球台风气象可视化实现
前端·vue.js·cesium
kyriewen2 小时前
响应式设计:一套代码,手机平板电脑全拿下
前端·css·html
姝然_95272 小时前
Jetpack Compose Shape 基础使用
前端
cxxcode2 小时前
ArrayBuffer / TypedArray / Blob / File 关系与操作指南
前端
叫我一声阿雷吧2 小时前
【JS 实战案例】用 JS 实现页面滚动到指定位置(带动画)
javascript·页面交互·js实战案例·平滑滚动·前端零基础·锚点导航