在前端的需求开发中,可能会遇到后端已经输出接口文档,但是代码还没有实现完成的情况,前端不得不等后端接口写好后再请求数据,或者在js中手写死数据来模拟,这样效率会比较低而且浪费时间。在这种场景下,如果前端想要获取数据应用于开发的话,可以使用mock.js模拟一个mock接口去请求,来拦截ajax请求,生成伪数据。
mock.js的优点与缺点
优点: 配置简单、前后端分离、可随机生成大量的数据、数据类型丰富。
缺点: mock.js只是拦截地址,直接返回mock数据,并不会直接发送真实的请求,所以在控制台的network看不到请求,只能通过console打印查看数据(Apifox mock的接口可以看到network请求,详情在文末)。
mockjs官方网址: mockjs.com
mock.js在vue项目中的应用
首先安装mock.js
npm install mockjs
一般搭配axios发起网络请求
npm install axios
在项目中新建mock文件并初始化mock
可以在项目根目录创建mock文件夹,里面新建index.js文件,该文件中引入mock模块
import Mock from 'mockjs' //引入mock
Mock.setup({ //设置拦截ajax请求的响应时间,若干时间后才会返回响应内容
timeout:'200-600'
});
let configArray=[];
const files = require.context('.',true,/.js$/); //使用webpack的require.context()遍历所有mock文件
files.keys().forEach((key) => {
if(key==='./index.js'){
return
}
configArray=configArray.concat(files(key).default)
});
configArray.forEach((item)=>{ //注册所有的mock服务
for(let[path,target] of Object.entries(item)){
let protocol=path.split('|');
Mock.mock(new RegExp('^' + protocol[1]),protocol[0],target)
}
})
在入口文件main.js(next-cli项目为pages下的index.js)中导入mock文件
import './mock/index.js'
在mock文件夹中新建mockApi.js单独存放需要模拟的接口数据
最常用接口数据为json结构,用mock定义需要模拟的json数据结构,并随机生成若干条,并通过export暴露出来模拟的接口路径与请求方式
import Mock from 'mockjs'
let userList = {
code: 200,
message:'success',
data:{
total:100,
'userInfo|100':[{
id:'@guid',
date:'@date(yyyy-MM-dd hh:mm)',
name:'@cname',
'age|20-35':1,
address:'@city(true)',
'job|1':['前端开发工程师','后端开发工程师','UI设计师','测试工程师'],
"position|1-5":1
}]
}
};
export default {
'get|/queryUserList':userList
}
用axios调用该接口获取数据
为方便管理与防止冗余过多,可以封装axios调用的接口:
- 在根目录新建api文件夹,并在其中创建index.js文件
import axios from 'axios'
export const Api = new (class { //定义Api类并暴露出来
constructor() { //单独管理接口路径
this.userListApi = '/queryUserList'
}
getUserList() { //定义调用接口的方法,返回axios调用接口的结果
return axios.get('/queryUserList').then((res) => res.data)
}
})()
调用接口获取数据:
- 1.在指定场景调用对应接口的方法,如组件进入时,在mounted生命周期调用
mounted(){
Api.getUserList().then((res) => {
this.realList=res.data.userInfo
this.tableLength=res.data.total
})
}
控制台打印返回的res数据: userInfo中为mock随机生成的数据:
- 2.将获取到的数据渲染在页面上
<div class="table-area">
<el-table :data="realList.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)" stripe style="width: 100%" border>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="date" label="入职日期" width="180"></el-table-column>
<el-table-column prop="age" label="年龄" width="180"></el-table-column>
<el-table-column prop="address" label="户籍地址"></el-table-column>
<el-table-column prop="job" label="职位"></el-table-column>
<el-table-column prop="position" label="职级">
<template #default="scope">
<div v-if="scope.row.position == 5">
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
</div>
<div v-if="scope.row.position == 4">
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-off"></i>
</div>
<div v-if="scope.row.position == 3">
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-off"></i>
<i class="el-icon-star-off"></i>
</div>
<div v-if="scope.row.position == 2">
<i class="el-icon-star-on"></i>
<i class="el-icon-star-on"></i>
<i class="el-icon-star-off"></i>
<i class="el-icon-star-off"></i>
<i class="el-icon-star-off"></i>
</div>
<div v-if="scope.row.position == 1">
<i class="el-icon-star-on"></i>
<i class="el-icon-star-off"></i>
<i class="el-icon-star-off"></i>
<i class="el-icon-star-off"></i>
<i class="el-icon-star-off"></i>
</div>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="10"
layout="total, sizes, prev, pager, next, jumper"
:total="tableLength"
></el-pagination>
</div>
- 3.运行效果:
mock.js常用语法
// 定义数据类型
var data = Mock.mock({
// 自动生成20条数据
"data|20": [{
// 从ID为1开始,每条数据ID自动加1
"ID|+1": 1,
// 随机生成一个中文名
'name': "@cname",
// 随机生成数组中的1项
'type|1': ["美的","集团","电商"],
// 随机生成包含5-20个中文的字符串
'text|5-20': '@cword',
// 随机生成一个范围0-10的数字
'account|0-10': 1,
// 随机生成一个日期时间,括号内为时间戳格式
"date":"@date('yyyy-MM-dd HH:mm:ss')"
// 随机生成一个日期,举例:2023-02-03
"date":"@date"
// 随机生成一个大小100×100,颜色随机,格式为png的图片地址
"imgUrl": "@Image('100x100','@color','png')",
// 随机生成一个颜色,结果为16进制色值代码
"color": "@color",
// 随机生成一个布尔值,true或false
"is": "@boolean",
// 随机生成一个英文名
"name": "@name",
// 随机生成一个市
"ccity":"@city"
}]
})
便捷的接口Mock工具:Apifox
如果想要在network中查看mock接口的请求,可以使用Apifox
Apifox的优点:
根据json数据可以自动生成mock模拟的数据,内置mock的服务器对AJAX的请求进行拦截,不需要在前端的项目中添加mock.js的代码,减少了代码量,适合团队开发使用
Apifox的使用方法:
1.UniAccess安全助手的软件商城里有Apifox,可在软件商城直接安装:
2.安装后登录软件Apifox,进行如下操作:
3.填写接口信息,请求方式、接口路径、服务类型、返回响应是必填项,在返回响应中用mock.js语法配置调用接口后期望的返回数据:
4.运行配置好的接口,检验返回接口是否正确,Apifox涵盖Postman的功能,也可以在Apifox中调试接口:
5.在项目中的API配置中直接调用Apifox生成的mock接口路径,接口的请求可以在network中查看到:
import axios from 'axios'
export const Api = new (class {
constructor() {
this.userListApi = 'http://127.0.0.1:4523/mock/2253158/queryuserlist' //Apifox mock的接口路径
}
getUserList() {
return axios.get(this.userListApi).then((res) => res)
}
})()
6.接口获取到的数据渲染在页面上: