mockjs介绍及使用

js yekong

Mock.js是一个用于生成模拟数据的JavaScript库,它可以用于前端开发中模拟后端API接口的响应数据。Mock.js可以帮助开发人员在没有实际后端服务器的情况下进行前端开发和调试,同时也能提供一些随机化数据,以模拟不同场景下的接口响应。

特点和功能

  • 自动生成随机数据:Mock.js可以根据一些预定义的模板和规则,生成具有随机性的模拟数据,如字符串、数字、数组等。
  • 支持多种数据类型:Mock.js支持生成各种常见的数据类型,包括字符串、数字、布尔值、数组、对象、日期等。
  • 支持拦截请求:Mock.js可以拦截Ajax请求,并根据定义的模拟数据规则,返回模拟的响应数据,从而使前端可以在开发过程中独立于后端进行测试和调试。
  • 丰富的数据模板:Mock.js提供了丰富的数据模板,如占位符(placeholder)、正则表达式、自定义函数等,可以用于生成复杂的模拟数据。
  • 轻量且易于使用:Mock.js是一个轻量级的库,只需要引入一个JavaScript文件即可使用,并且提供了简洁易用的API。

示例

以下是一个简单的Mock.js示例,用于模拟一个简单的用户数据接口:

import Mock from 'mockjs';

Mock.mock('/api/users', 'get', {
  'users|5': [
    {
      'id|+1': 1,
      'name': '@name',
      'age|18-60': 0
    }
  ]
});

上述代码将拦截GET请求到/api/users接口,并返回一个包含5个用户对象的数组,每个用户对象包含id、name和age属性,其中id递增、name为随机的名字、age在18到60之间的随机数。

使用Mock.js可以使前端开发更加高效,因为它提供了一种简单的方式来模拟后端数据,使前端开发人员能够独立于后端进行开发和测试。然而,在最终部署到生产环境时,应该确保移除Mock.js的代码,以避免不必要的性能开销。

vue3 vite中使用mockjs

安装依赖

pnpm i mockjs vite-plugin-mock@2.9.8

vite.config.js配置vite-plugin-mock的使用

import {viteMockServe} from 'vite-plugin-mock'

export default defineConfig({
	plugins:[
  	vue(),
    viteMockServe({
        mockPath: 'mock',//设置模拟数据的存储文件夹
        logger: true,//是否在控制台显示请求日志
        localEnabled: true,//设置是否启用本地mock文件
        prodEnabled: true//设置打包是否启用mock功能
    })
  ]
})

编写api接口

在src同级目录下创建mock目录,并在目录下创建index.ts
创建mockjs文件

import { MockMethod } from 'vite-plugin-mock';
import Mock from 'mockjs';

const mock: MockMethod[] = [
    {
        url: '/api/personTime',
        method: 'get',
        response: () => {
            return {
                status: 200,
                message: 'success',
                data: Mock.mock({
                    'users|5': [
                        {
                            'id|+1': 1,
                            'name': '@name',
                            'age|18-60': 0,
                        },
                    ],
                }),
            };
        },
    },
];

export default mock;

配置完成后,可以看到mock日志请求输出
mock日志请求输出

api调用封装

创建文件 src/api/api/LargeScreenData.js

import request from '../request'

// 人次占比
export function personTime(data) {
    return request({
        url: '/api/personTime',
        method: 'get',
        data
    })
}

创建文件 src/api/ipConfig.js

var url1 = '' // 正式接口
var url2 = '' // 调试接口
var ip = process.env.NODE_ENV === 'production' ? '' : ''

export const devIp = ip
export const testIp = ip
export const timing = 10000

创建文件 src/api/request.js

import axios from 'axios'
// import {Message} from 'element-ui'
import {devIp} from '@/api/ipConfig'
// 刷新token的一个开关,防止重复请求
let isRefreshing = true;

const service = axios.create({
    baseURL: devIp + '', // 测试IP
    timeout: 100000, // request timeout
})

// request interceptor
service.interceptors.request.use(config => {
    let token = localStorage.getItem('access_token')
    if (token) {
        config.headers['Authorization'] = 'Basic c2FiZXI6c2FiZXJfc2VjcmV0' // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
        config.headers['Blade-Auth'] = token // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
    }
    return config
}, error => {
    Promise.reject(error)
})

// respone interceptor
service.interceptors.response.use(
    // response => response,
    response => {
        const res = response.data
        return res;
    },
    error => {
        if (error.response.data.code == 401) {
            if (isRefreshing) {
                isRefreshing = false;
                return refreshToken().then((res) => {
                    const data = res.data;
                    if (data.access_token) {
                        localStorage.setItem('access_token', data.access_token)
                        // 已经刷新了token,将所有队列中的请求进行重试
                        window.location.reload();
                    } else {
                        return false;
                    }
                }).catch(() => {
                    return false;
                }).finally(() => {
                    isRefreshing = true
                })
            }
        }
        return Promise.reject(error)
    })

// 刷新token请求
function refreshToken() {
    return axios.post(`${devIp}/api/blade-auth/oauth/token?tenantId=000000&username=DP001&password=efc3d451b28e58fdbffde31ec4c37b86&grant_type=password&scope=all&type=account`, null, {
        headers: {
            'Tenant-Id': '000000',
            'Authorization': 'Basic c2FiZXI6c2FiZXJfc2VjcmV0'
        }
    });
}

export default service

接口请求

import {personTime} from '@/api/api/LargeScreenData'
getData() {
  var that = this;
  personTime().then(res => {
    console.log(res)
  }).catch(err => {
  })
},

请求结果

main.js配置

因为这里打包后也要使用mockjs所以我们这里需要配置一下。

import {createProdMockServer} from 'vite-plugin-mock/es/createProdMockServer'
import mock from './mock/'

// mock 生产环境时打包
if (process.env.NODE_ENV === 'production') {
    createProdMockServer(mock)
}

数据生成

生成20组数据

Mock.mock({
    'data|20': [{
        'site': '场所1',
        'name': '告警名称',
        'date': '@date("yyyy/MM/dd HH:mm:ss")',
    }]
})

date日期限制在2023年初到现在的日期

要在Mock.js中生成指定日期范围内的随机日期,我们可能需要自定义一个函数,该函数返回在指定范围内的随机日期。在Mock.js中,可以使用Mock.Random.extend()方法扩展自定义的随机数据生成函数。

以下是一个例子,定义一个函数,返回2023年初到现在的随机日期:


import dayjs from 'dayjs'

Mock.Random.extend({
    dateRange: function () {
        var start = new Date(2023, 0, 1).getTime(); // 2023年初
        var now = new Date().getTime(); // 当前日期
        return dayjs(new Date(start + Math.random() * (now - start))).format("YYYY-MM-DD HH:mm:ss");
    }
});

Mock.mock({
    'data|20': [{
        'site': '场所1',
        'name': '告警名称',
        'date': '@dateRange',
    }]
});

因为mockjs数据文件是用ts写的,引入dayjs可能会报错,引入dayjs报错解决办法,也可以不用dayjs格式化,用原始写法处理

Mock.Random.extend({
    dateRange: function () {
        var start = new Date(2023, 0, 1).getTime(); // 2023年初
        var now = new Date().getTime(); // 当前日期
        var date = new Date(start + Math.random() * (now - start));

        var year = date.getFullYear();
        var month = ("0" + (date.getMonth() + 1)).slice(-2); // Months are zero indexed, so we add one
        var day = ("0" + date.getDate()).slice(-2);
        var hour = ("0" + date.getHours()).slice(-2);
        var minute = ("0" + date.getMinutes()).slice(-2);
        var second = ("0" + date.getSeconds()).slice(-2);

        return `${year}-``{month}-``{day} ``{hour}:``{minute}:${second}`;
    }
});

在上述代码中,我们首先使用Mock.Random.extend()方法扩展了一个新的随机数据生成函数dateRange,该函数生成2023年初到现在的随机日期。然后在mock数据中,我们使用'@dateRange'来调用该函数,生成我们需要的日期数据。

最后一点,需要注意的是,Mock.js是按需生成数据的,也就是说,如果你的代码在2023年之后运行,生成的日期还会包括2023年后的日期。

结果:

{"data":[{"site":"场所1","name":"告警名称","date":"2023-04-14 18:00:59"},{"site":"场所1","name":"告警名称","date":"2023-05-07 12:03:07"}]}

生成固定标题加随机数字实例

数组数量固定4个,两组数字随机1-100,生成实例。

{
    url: '/api/personTime',
    method: 'get',
    response: () => {
        const titles = ['门诊', '急诊', '体检', '入院'];
        const users = titles.map(title => {
            return {
                title,
                num: Mock.Random.integer(1, 100),
                num2: Mock.Random.integer(1, 100),
            };
        });

        return {
            status: 200,
            message: 'success',
            data: {...users},
        };
    },
}

获取最近10年的年份

获取最近10年的年份,每个年份携带3个字段数值为1-100随机变化

{
    url: '/api/numberOfOperationsTrend',
    method: 'get',
    response: () => {
        const currentYear = new Date().getFullYear();
        const titles = Array.from({length: 10}, (_, i) => (currentYear - i).toString()).reverse();

        const users = titles.map(title => {
            return {
                title,
                value1: Mock.Random.integer(1, 100),
                value2: Mock.Random.integer(1, 100),
                value3: Mock.Random.integer(1, 100),
            };
        });

        return {
            status: 200,
            message: 'success',
            data: users,
        };
    },
},

生成数据下一条数据要比上一条数据大

生成列表数据,因为数据下一个一定比上一个要大,所以随机数要进行调整。

{
    url: '/api/house-prices',
    method: 'get',
    response: () => {
        let lastValue = 0;
        const data = [
            {name: '一室', value: lastValue = Mock.Random.natural(1, 100)},
            {name: '两室', value: lastValue = Mock.Random.natural(lastValue + 1, 100)},
            {name: '三室', value: lastValue = Mock.Random.natural(lastValue + 1, 100)},
            {name: '四室', value: lastValue = Mock.Random.natural(lastValue + 1, 100)},
            {name: '以上', value: Mock.Random.natural(lastValue + 1, 100)}
        ];
        return {
            data,
            message: '成功',
            code: 0
        }
    },
}

get传参

通过get获取前端传参,通过options.query获取传参

// 白天晚上告警统计
// vue3 mockjs 生成白天晚上告警统计接口 name 日期(yyyy-mm-dd) value 随机1-100
{
    url: '/api/dayNightAlertStatistics',
    method: 'get',
    response: (options) => {
        function generateAlertStatistics(startDate, endDate) {
            const data = [];
            let start = new Date(startDate);
            let end = new Date(endDate);

            for (let d = start; d <= end; d.setDate(d.getDate() + 1)) {
                const dateStr = `${d.getFullYear()}-``{String(d.getMonth() + 1).padStart(2, '0')}-``{String(d.getDate()).padStart(2, '0')}`;
                data.push({
                    name: dateStr,
                    value: Mock.Random.integer(1, 100),
                });
            }

            return data;
        }

        const startDate = options.query.startDate;
        const endDate = options.query.endDate;
        let data;

        if (startDate && endDate) {
            data = generateAlertStatistics(startDate, endDate);
        } else {
            const end = new Date();
            const start = new Date();
            start.setDate(end.getDate() - 9); // 获取最近10天的数据
            data = generateAlertStatistics(start, end);
        }
        return {
            data: data,
            message: '成功',
            code: 0
        }
    },
},

封装

使用qs 对参数进行处理


// 白天晚上告警统计
export function dayNightAlertStatistics(data) {
    return request({
        url: '/api/dayNightAlertStatistics?' + qs.stringify(data),
        method: 'get',
        data
    })
}

请求接口

async getData2() {
  try {
    const res = await dayNightAlertStatistics({startDate: this.startDate, endDate: this.endDate});
    this.list2 = res.data;
  } catch (err) {
    console.error(err);
  }
},

生成12个月份数据

mockjs 生成1-12月数据 name为月份 value为-45到45之间

const generateMonthlyData = () => {
  const data = [];
  for (let i = 1; i <= 12; i++) {
    data.push({
      name: i + '月',
      value: Mock.Random.integer(-45, 45)
    });
  }
  return data;
};

const monthlyData = generateMonthlyData();
console.log(monthlyData);

项目应用

数据可视化大屏 消防数据大屏可视化

酒店数据可视化大屏

vue3 数据可视化大屏 - 网络信息化大数据平台

喜欢