前端模拟数据与接口拦截实践

219 阅读2分钟

Mock.js使用指南:前端模拟数据与接口拦截实践

Mock.js是一个优秀的前端数据模拟库,能够帮助开发者在后端接口未完成时进行前端开发,通过拦截Ajax请求并返回模拟数据。下面我将详细介绍如何使用Mock.js。

Mock.js核心功能

  • 生成随机数据:使用模板语法生成结构化随机数据
  • 拦截Ajax请求:拦截XMLHttpRequest和fetch请求
  • 模拟RESTful API:支持GET、POST、PUT、DELETE等请求方法
  • 数据模板定义:使用简洁的语法定义数据结构

基础使用示例

1. 安装Mock.js

npm install mockjs --save-dev
# 或
yarn add mockjs --dev

2. 基本使用

// 引入Mock.js
import Mock from 'mockjs';

// 定义模拟数据模板
const mockData = Mock.mock({
  'list|10': [{
    'id|+1': 1,
    'name': '@cname',
    'age|18-60': 1,
    'email': '@email',
    'address': '@county(true)'
  }]
});

console.log(mockData);

3. 拦截Ajax请求

// 拦截GET请求
Mock.mock('/api/users', 'get', {
  code: 200,
  message: 'success',
  'data|5-10': [{
    id: '@id',
    name: '@cname',
    avatar: Mock.Random.image('100x100')
  }]
});

// 拦截POST请求(如登录接口)
Mock.mock('/api/login', 'post', function(options) {
  const { username, password } = JSON.parse(options.body);
  
  if (username === 'admin' && password === '123456') {
    return {
      code: 200,
      message: '登录成功',
      token: Mock.mock('@guid'),
      username,
      roles: ['admin']
    };
  } else {
    return {
      code: 401,
      message: '用户名或密码错误'
    };
  }
});

在Vue/React项目中集成Mock.js

项目结构建议

src
├── mock
│   ├── index.js       # Mock入口文件
│   ├── user.js        # 用户相关接口
│   ├── product.js     # 产品相关接口
│   └── utils.js       # Mock工具函数
└── main.js            # 项目入口

示例:用户模块(user.js)

import Mock from 'mockjs';

const users = Mock.mock({
  'list|100': [{
    id: '@id',
    name: '@cname',
    'age|20-50': 1,
    gender: '@pick(["男", "女"])',
    phone: /1[3-9]\d{9}/,
    email: '@email',
    address: '@county(true)',
    createTime: '@datetime'
  }]
});

export default [
  // 获取用户列表
  {
    url: '/api/users',
    method: 'get',
    response: (config) => {
      const { page = 1, size = 10 } = config.query;
      const start = (page - 1) * size;
      const end = page * size;
      
      return {
        code: 200,
        message: 'success',
        data: {
          list: users.list.slice(start, end),
          total: users.list.length
        }
      };
    }
  },
  
  // 登录接口
  {
    url: '/api/login',
    method: 'post',
    response: (req) => {
      const { username, password } = req.body;
      
      if (username === 'admin' && password === 'admin123') {
        return {
          code: 200,
          message: '登录成功',
          data: {
            token: Mock.mock('@guid'),
            username,
            roles: ['admin'],
            avatar: Mock.Random.image('50x50')
          }
        };
      } else if (username === 'user' && password === 'user123') {
        return {
          code: 200,
          message: '登录成功',
          data: {
            token: Mock.mock('@guid'),
            username,
            roles: ['user'],
            avatar: Mock.Random.image('50x50')
          }
        };
      } else {
        return {
          code: 401,
          message: '用户名或密码错误'
        };
      }
    }
  },
  
  // 获取用户信息
  {
    url: '/api/userInfo',
    method: 'get',
    response: (req) => {
      const token = req.headers?.authorization;
      
      if (token) {
        return {
          code: 200,
          message: 'success',
          data: {
            username: 'admin',
            roles: ['admin'],
            avatar: Mock.Random.image('50x50'),
            permissions: ['dashboard', 'user', 'product']
          }
        };
      } else {
        return {
          code: 401,
          message: '未授权'
        };
      }
    }
  }
];

Mock入口文件(index.js)

import Mock from 'mockjs';
import user from './user';
import product from './product';

// 设置请求延迟时间
Mock.setup({
  timeout: '200-600'
});

// 注册所有mock模块
const modules = [...user, ...product];

modules.forEach(item => {
  Mock.mock(
    new RegExp(item.url),
    item.method,
    item.response
  );
});

// 打印已注册的mock接口
console.log('[Mock] 已注册接口:');
modules.forEach(item => {
  console.log(`- ${item.method.toUpperCase()} ${item.url}`);
});

// 导出Mock,便于其他文件使用
export default Mock;

Mock.js常用语法

语法描述示例
`'namemin-max'`重复属性`'list5-10': [{...}]`
`'namecount'`固定重复次数`'list5': [{...}]`
`'name+1'`属性值自增`'id+1': 1`
'name'属性值name: 'John'
'@name'随机名称name: '@cname'
'@date'随机日期date: '@date'
'@image'随机图片avatar: '@image(100x100)'
'@color'随机颜色color: '@color'
'@pick'从数组中随机选择gender: '@pick(["男", "女"])'