JS Mock数据使用教程

Mock数据是前端开发中非常重要的技术,它允许你在后端接口尚未完成时,模拟数据来进行前端开发和测试。以下是JS中使用Mock数据的详细教程。

1. 为什么需要Mock数据

  • 前后端分离开发时,前端不依赖后端接口
  • 测试各种边界条件和异常情况
  • 快速原型开发
  • 自动化测试

2. 简单的Mock数据实现

2.1 直接定义数据对象

// mock/user.js
export const mockUsers = [
  { id: 1, name: '张三', age: 25 },
  { id: 2, name: '李四', age: 30 },
  { id: 3, name: '王五', age: 28 }
]
// 使用
import { mockUsers } from './mock/user'
console.log(mockUsers)

2.2 使用函数生成Mock数据

function mockUser(count = 5) {
  const users = []
  for (let i = 1; i <= count; i++) {
    users.push({
      id: i,
      name: `用户${i}`,
      age: Math.floor(Math.random() * 30) + 18,
      email: `user${i}@example.com`
    })
  }
  return users
}
console.log(mockUser(3))

3. 使用Mock.js库

Mock.js 是一个强大的Mock数据生成库。

3.1 安装

npm install mockjs
# 或
yarn add mockjs

3.2 基本使用

import Mock from 'mockjs'
// 基本用法
const data = Mock.mock({
  'list|5': [{
    'id|+1': 1,
    'name': '@cname',
    'age|18-60': 1,
    'email': '@email',
    'address': '@county(true)',
    'date': '@date("yyyy-MM-dd")'
  }]
})
console.log(data)

3.3 常用数据模板

  • 字符串
    • 'name|min-max': string 重复string min-max次
    • 'name|count': string 重复string count次
    • 'name': '@first' 随机英文名
    • 'name': '@cname' 随机中文名
    • 'email': '@email' 随机邮箱
  • 数字
    • 'age|1-100': 1 1-100之间的随机数
    • 'score|1-100.1-3': 1 带1-3位小数的随机数
  • 布尔值
    • 'status|1': true 50%概率为true
    • 'status|1-9': true 1/10概率为true
  • 对象
    • 'obj|2': {...} 从属性中随机选取2个
    • 'obj|1-3': {...} 从属性中随机选取1-3个
  • 数组
    • 'array|1': [...] 从数组中随机选取1个元素
    • 'array|+1': [...] 按顺序选取元素
    • 'array|1-10': [...] 重复数组元素1-10次

4. 拦截AJAX请求

4.1 使用Mock.js拦截

import Mock from 'mockjs'
// 模拟GET请求
Mock.mock('/api/users', 'get', {
  'users|5-10': [{
    'id|+1': 1,
    'name': '@cname',
    'age|18-60': 1
  }]
})
// 模拟POST请求
Mock.mock('/api/login', 'post', function(options) {
  const { username, password } = JSON.parse(options.body)
  if (username === 'admin' && password === '123456') {
    return Mock.mock({
      code: 200,
      message: '登录成功',
      token: '@guid'
    })
  } else {
    return Mock.mock({
      code: 401,
      message: '用户名或密码错误'
    })
  }
})
// 使用fetch测试
fetch('/api/users')
  .then(res => res.json())
  .then(data => console.log(data))
fetch('/api/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    username: 'admin',
    password: '123456'
  })
})
.then(res => res.json())
.then(data => console.log(data))

4.2 使用axios-mock-adapter

npm install axios axios-mock-adapter
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'
// 创建mock适配器
const mock = new MockAdapter(axios)
// 模拟GET请求
mock.onGet('/api/users').reply(200, {
  users: [
    { id: 1, name: '张三' },
    { id: 2, name: '李四' }
  ]
})
// 模拟带参数的GET请求
mock.onGet('/api/user').reply(config => {
  const id = config.params.id
  return [200, { id, name: `用户${id}`, age: 25 }]
})
// 模拟POST请求
mock.onPost('/api/login').reply(config => {
  const { username, password } = JSON.parse(config.data)
  if (username === 'admin' && password === '123456') {
    return [200, { token: 'mock-token' }]
  } else {
    return [401, { message: '认证失败' }]
  }
})
// 使用
axios.get('/api/users').then(response => {
  console.log(response.data)
})
axios.get('/api/user', { params: { id: 1 } }).then(response => {
  console.log(response.data)
})
axios.post('/api/login', {
  username: 'admin',
  password: '123456'
}).then(response => {
  console.log(response.data)
})

5. 高级Mock技巧

5.1 动态响应

Mock.mock('/api/dynamic', req => {
  // 可以访问请求方法、URL、参数等
  console.log(req)

  return {
    code: 200,
    data: {
      method: req.method,
      url: req.url,
      time: Mock.mock('@now')
    }
  }
})

5.2 分页数据模拟

Mock.mock(/\/api\/users\/page/, 'get', options => {
  const query = new URLSearchParams(options.url.split('?')[1])
  const page = parseInt(query.get('page')) || 1
  const size = parseInt(query.get('size')) || 10

  const total = 100
  const totalPages = Math.ceil(total / size)

  const data = Mock.mock({
    [`list|${size}`]: [{
      'id|+1': (page - 1) * size + 1,
      'name': '@cname',
      'age|18-60': 1,
      'email': '@email'
    }]
  })

  return {
    code: 200,
    data: {
      page,
      size,
      total,
      totalPages,
      list: data.list
    }
  }
})

5.3 延迟响应

Mock.setup({
  timeout: '200-600' // 随机200-600ms延迟
})
Mock.mock('/api/delay', {
  'data|5': [{
    'id|+1': 1,
    'name': '@cname'
  }]
})

6. 结合前端框架使用

6.1 在Vue中使用

// src/mock/index.js
import Mock from 'mockjs'
Mock.mock('/api/data', 'get', {
  'list|10': [{
    'id|+1': 1,
    'name': '@cname'
  }]
})
// 在main.js中引入
import './mock'
// 组件中使用
this.$http.get('/api/data').then(res => {
  this.list = res.data.list
})

6.2 在React中使用

// src/setupTests.js (Create React App)
import Mock from 'mockjs'
Mock.mock('/api/data', 'get', {
  'list|10': [{
    'id|+1': 1,
    'name': '@cname'
  }]
})
// 组件中
useEffect(() => {
  fetch('/api/data')
    .then(res => res.json())
    .then(data => setList(data.list))
}, [])

7. 生产环境关闭Mock

// mock/index.js
import Mock from 'mockjs'
if (process.env.NODE_ENV === 'development') {
  Mock.mock('/api/data', 'get', {
    // mock数据
  })
}
// 或者在webpack配置中通过环境变量控制

8. 其他Mock工具推荐

  1. json-server: 快速创建REST API
    npm install -g json-server
    json-server --watch db.json
    
  2. faker.js: 生成大量逼真的假数据
    import { faker } from '@faker-js/faker'
    console.log(faker.person.fullName())
    
  3. msw (Mock Service Worker): 基于Service Worker的API Mock
    import { setupWorker, rest } from 'msw'
    const worker = setupWorker(
      rest.get('/api/user', (req, res, ctx) => {
        return res(
          ctx.json({ name: '张三' })
        )
      })
    )
    worker.start()
    

9. 最佳实践

  1. 将Mock数据与业务代码分离
  2. 使用随机数据而不是固定数据
  3. 模拟各种网络状态(成功、失败、超时)
  4. 模拟真实的数据结构和字段名
  5. 在团队中保持Mock数据的一致性
  6. 及时更新Mock数据以匹配API文档变更 通过以上方法,你可以有效地使用Mock数据来提高开发效率,减少对后端API的依赖,并提高前端代码的质量和可靠性。









results matching ""

    No results matching ""