XingYun blog
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具

XingYun

冲!
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具
  • 3个提升Vue性能的写法
  • 重读Vue文档
  • moment.js给定时间获取自然月、周的时间轴
  • Vue虚拟dom与Diff算法
  • 深入响应式原理
  • Echart样例
  • 我的Vue指令库
  • 滚动到底部加载更多
  • 实现一键换肤
  • 手写Vue数据劫持
  • vue-router核心原理与手写实现
  • computed和watch
  • vue数组为什么不是响应式
  • v-for为什么不能用index做key
  • webpack loader和plugin
  • keep-alive组件原理
  • vue插槽进化
  • Vue多层嵌套组件
  • vue生命周期hook
  • vue监听dom元素的resize事件
  • 前端打包需要gzip压缩吗
  • 实现水波浪进度球
  • Vue
XingYun
2022-09-13
目录

使用mockjs模拟复杂数据

# 1、关于 Mock.js

# 1.1 Mock.js 能做什么?

  • 生成随机数据
  • 能拦截 Ajax 请求

# 1.2 我为什么选择 Mock.js 模拟数据?

  • URL 支持正则匹配, 也就是可以批量拦截接口
  • 低耦合 :无需修改既有代码,即可拦截 Ajax 请求,返回模拟的响应数据。
  • 数据类型多样: 支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。

# 2. Vue 项目引入 mock.js

我将 mockjs 放在了 src 目录下

然后在 main.js 中引入

import './mock/mock.ts'
1

我们一般只需要在 dev 环境中 mock 数据, 所以一般会加个环境判断

// mock.ts
import Mock from 'mockjs'
if (process.env.NODE_ENV === 'development') {
  initMock()
}

Mock.setup({ timeout: 1000 }) // 模拟数据返回的延时

function initMock() {
  Mock.mock('/api/news', data)
}
1
2
3
4
5
6
7
8
9
10
11

# 2.1 基本使用

Mock.mock()函数签名

Mock.mock( requestUrl, requestType?, template | function( options ) )
1

requestUrl
可选参数,表示需要拦截的 Ajax URL,可以是 URL 字符串或 URL 正则。
例如 //domain/list.json/、'/domian/list.json'。

requestType
可选参数,表示需要拦截的 Ajax 请求类型。
例如 GET、POST、PUT、DELETE 等。

template
可选参数,表示数据模板,可以是对象或字符串。

function(options)
可选参数,表示用于生成响应数据的函数。

options
指向本次请求的 Ajax 选项集,含有 url、type 和 body 三个属性

举个例子:

import Mock from 'mockjs'

function initMock() {
  Mock.mock('/api/news', 'get', {
    code: 'OK',
    results: [
      {
        id: '1',
        title: 'title1'
      },
      {
        id: '2',
        title: 'title2'
      }
    ]
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

发起请求:

// in any.vue
async getNews() {
    const { data: res } = await this.$http({ url: "/api/news" });
    console.log("get", res);
}
1
2
3
4
5

这段代码生效后 /api/news 这个接口就被拦截了, 在浏览器中的网络请求中也看不到了, 但是请求会正常收到 mock 的数据, 正常打印

# 2.2 引入正则 支持批量拦截

如果你的项目中所有接口都有 /api/, url 中每次都要加这个前缀显得有点多余

如果你想拦截

/api/news/content/getNews
/api/news/content/getArticle
/api/news/content/getBooks
1
2
3

需要将这个接口重复三遍, 这显然是不能接受的.

这里我们可以用正则来 批量拦截

Mock.mock(/news\/content/, getRes(data))
1

这样所有包含 /news/content 的 url 都会被拦截

这里还有一个痒点: 假设我模拟 url /news/content/getNews/day/night, 拷贝过来后我得在每个 / 前面加上正则的转译符 \

 /news\/content\/getNews\/day\/night
1

挺麻烦, 为了解决这个问题我写了个方法

export function transformUrlToReg(url: string) {
  if (url[0] === '/') {
    url = url.substring(1)
  }
  if (url[url.length - 1] === '/') {
    url = url.substring(0, url.length - 2)
  }
  let reg = new RegExp(url)
  return reg
}
1
2
3
4
5
6
7
8
9
10

再加上一个批量 mock 的方法

type MockType = {
  url: string
  obj: any
}
const mockList: MockType[] = [
  {
    url: 'algorithm-manage/devices/algo-device-list', // 状态面板
    obj: {
      deviceName: '智能边缘计算设备-公交总公司离行式自助银行',
      deviceIp: '128.96.123.203',
      algoVersion: '2.4.0.8370',
      orgName: '省分行本部',
      partName: '公交总公司离行式自助银行',
      orgId: '34000000000489229',
      deviceId: '9e1a6d63da27886f7dee-wuhan-monitcenter-203-ccbft-in'
    }
  },
  {
    url: 'traffic/person-traffic-statistic/time-range-newest-record-list/', // 人员轨迹左侧人员列表
    obj: {
      personId: '56124513524-51-4513-56-25-',
      personName: '@cname',
      leastCaptureTime: '2021-03-30 14:14:08',
      totalNumber: 2,
      imageUrl: '@dataImage',
      faceStoreName: '@ctitle'
    }
  }
]

function initMock() {
  mockList.forEach((item) => {
    Mock.mock(transformUrlToReg(item.url), (params) => {
      return generatePaginationData(params, item.obj)
    })
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

现在如果要新拦截一个接口, 只需要在 mockList 中新配置一个就完成了

# 2.3 批量分页数据生成

列表分页数据在项目中很常见也需要 mock 下

我们的分页规则是

const body = {
  pageSize: 20,
  pageNum: 2,
  total: 100
}
1
2
3
4
5

我写了个方法

export const generatePaginationData = (
  params,
  obj: any = {},
  total: number = 100
) => {
  const body = JSON.parse(params.body) // request body数据
  let num =
    body.pageSize * body.pageNum < total
      ? body.pageSize
      : total - body.pageSize * (body.pageNum - 1)
  console.log('mock request params', params)
  let data = {
    list: (() => {
      let i = 1 + body.pageSize * (body.pageNum - 1)
      let res = Mock.mock({
        // 调用mock方法生成数据
        ['datas|' + num]: [
          {
            'id|+1': i, // id 每次加一
            ...obj
          }
        ]
      }).datas
      return res
    })(),
    total: total,
    pageNum: body.pageNum,
    pageSize: body.pageSize
  }
  console.log('mock response data', data)
  return getStandRes(data)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

这样就可以批量生成 MockType 的 obj 的数据了

上次更新: 2023/04/05, 09:41:10
最近更新
01
JavaScript-test
07-20
02
二维码的原理
07-20
03
利用ChatGPT优化代码
07-20
更多文章>
Theme by Vdoing | Copyright © 2021-2023 XingYun | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式