现在都着重于前后端分离以提高工作效率。当前端开发的时候,如果后端的接口没有写完,为了不影响工作效率,可以手动模拟后端接口。现在有许多数据模拟的库,但是许多都有所不足,比如json可以模拟后台数据,但却难以模拟数据的增删改。。。
MockJs |
MockJs可以生成随机数据,拦截 Ajax 请求。
MockJs优点 |
Hello MockJs |
//新建项目
mkdir mockjs-study
cd mockjs-study
//初始化项目
npm init -y
//安装
npm i mockjs -D
新建index.js文件,当前文件目录结构:
入门例子,现在看不懂没关系,继续看下文
// index.js
const Mock = require("mockjs");
let data=Mock.mock({
//对象有一个list属性,list是一个数组,包含有1到3个元素,每次运行生成的元素个数都在这个范围内
'list|1-3':[{
//list数据里面是对象,对象里面有id属性,是一个自增数,起始值为 1,每次增 1
'id|+1':1
}]
})
console.log(data);
语法规范 |
Mock.js 的语法规范包括两部分:
数据模板定义规范 |
数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值:
// 属性名 name
// 生成规则 rule
// 属性值 value
'name|rule': value
属性名 和 生成规则 之间用竖线 |
分隔。
生成规则是可选的,默认是'name|1': value
。
生成规则有以下格式:(dmin表示小数位最少有几位)
'name|min-max': value
'name|count': value
'name|min-max.dmin-dmax': value
'name|min-max.dcount': value
'name|count.dmin-dmax': value
'name|count.dcount': value
'name|+step': value
生成规则 的 含义 需要依赖 属性值的类型 才能确定。
属性值 中可以含有 @占位符
。
属性值 还指定了最终值的初始值和类型。
属性值是字符串 String |
☄ 'name|min-max': string
重复拼接 string 生成一个字符串,min<=重复次数<=max
'name|1-3':'hello'
// name: 'hello' or name: 'hellohello' or name: 'hellohellohello'
☄ 'name|count': string
重复拼接 count 次 string 生成一个字符串
'name|2':'hello'
// name: 'hellohello'
属性值是数字 Number |
☄ 'name|+step': number
初始值为 number,下一次该属性值自动加 step。
let data=Mock.mock({
'list|2':[{
'id|+2':1,
}]
})
console.log(data);//{ list: [ { id: 1 }, { id: 3 } ] }
☄ 'name|min-max': number
生成一个大于等于 min、小于等于 max 的整数,属性值 number 只是用来确定数据类型。
'name|1-3':10 //你可以写其他数字 效果都一样
//name: 1 or name: 2 or name: 3
☄ 'name|min-max.dmin-dmax': number
生成一个浮点数,整数部分大于等于 min、小于等于 max,小数部分保留 dmin 到 dmax 位。
'name|1-2.1-2':10
//name: 1.1 or name: 1.2 or name: 2.1 or name: 2.2
属性值是布尔型 Boolean |
☄ 'name|count': boolean
随机生成一个布尔值,值为 boolean 的概率是 count/(count+1),值为 !boolean 的概率是 1/(count+1)。
let data=Mock.mock({
'list|10':[{
'name|4':false
}]
})
console.log(data);
生成false值的概率是4/5 生成true值的概率是1/5
☄ 'name|min-max': value
随机生成一个布尔值,值为 value 的概率是 min / (min + max),值为 !value 的概率是 max / (min + max)。
let data=Mock.mock({
'list|10':[{
'name|1-5':false
}]
})
属性值是对象 Object |
☄ 'name|count': object
从属性值 object 中随机选取 count 个属性。
let data=Mock.mock({
'list|2':[{
'name|2':{
a:1,b:2,c:3}
}]
})
console.log(JSON.stringify(data));
//{"list":[{"name":{"c":3,"b":2}},{"name":{"b":2,"a":1}}]}
☄ 'name|min-max': object
从属性值 object 中随机选取 min 到 max 个属性。
let data=Mock.mock({
'list|2':[{
'name|2':{
a:1,b:2,c:3}
}]
})
console.log(JSON.stringify(data));
//{"list":[{"name":{"a":1,"b":2}},{"name":{"b":2,"a":1}}]}
属性值是数组 Array |
☄ 'name|count': array
从属性值 array 中随机选取 count 个元素,作为最终值。
'name|1':[1,2,3,4]
// name: 1 or name: 2 or name: 3 or name: 4
☄ 'name|+step': array
下一个属性从 array 当前 index 按顺序走 step 位,取该元素,作为下一个属性值。
let data=Mock.mock({
'list|4':[{
'name|+3':[1,2,3,4]
}]
})
console.log(data);
//{ list: [ { name: 1 }, { name: 4 }, { name: 3 }, { name: 2 } ] }
☄ 'name|min-max': array
重复拼接 min-max 次 array 生成一个新数组
let data=Mock.mock({
'list|4':[{
'name|1-3':[1,2,3,4]
}]
})
console.log(JSON.stringify(data));
//{"list":[{"name":[1,2,3,4]},{"name":[1,2,3,4]},{"name":[1,2,3,4,1,2,3,4]},{"name":[1,2,3,4,1,2,3,4]}]}
☄'name|count': array
重复拼接 count 次 array 生成一个新数组
let data=Mock.mock({
'list':[{
'name|2':[1,2,3,4]
}]
})
console.log(JSON.stringify(data));
//{"list":[{"name":[1,2,3,4,1,2,3,4]}]}
属性值是函数 Function |
☄ 'name': function
执行函数 function,取其返回值作为最终的属性值,函数的上下文为属性 ‘name’ 所在的对象。
function foo(){
return {
a:1,b:2,c:3}
}
let data=Mock.mock({
'list|2':[{
'name|2':foo()
}]
})
console.log(JSON.stringify(data));
//{"list":[{"name":{"b":2,"c":3}},{"name":{"b":2,"a":1}}]}
属性值是正则表达式 RegExp |
☄ 'name': regexp
根据正则表达式 regexp 反向生成可以匹配它的字符串。用于生成自定义格式的字符串。
let data=Mock.mock({
'regexp1': /[a-z][A-Z][0-9]/,
'regexp2': /\w\W\s\S\d\D/,
'regexp3': /\d{5,10}/
})
console.log(JSON.stringify(data));
//{"regexp1":"dT8","regexp2":"i:\t68;","regexp3":"817374"}
数据占位符定义规范 |
@占位符
@占位符(参数 [, 参数])
Mock.Random
中的方法。@占位符
Mock.Random.extend()
来扩展自定义占位符。@占位符(参数 [, 参数])
let data=Mock.mock({
name: {
first: '@FIRST',
middle: '@FIRST',
last: '@LAST',
full: '@first @middle @last'
}
})
console.log(data);
// {
// name: {
// first: 'Paul',
// middle: 'David',
// last: 'Johnson',
// full: 'Paul David Johnson'
// }
// }
Mock.Random |
Mock.Random 是一个工具类,用于生成各种随机数据。不必刻意学习,具体案例使用 官网案例 都有。
Mock.Random 的方法在数据模板中称为『占位符』,书写格式为 @占位符(参数 [, 参数])
。
var Random = Mock.Random
// Random.city()
Random.city()//"铁岭市"
Mock.mock('@city')//"宝鸡市"
Mock.mock('@city()')//"澳门半岛"
// Random.city( prefix )
Random.city(true)//"江西省 鹰潭市"
Mock.mock('@city(true)')//"甘肃省 兰州市"
Mock.Random 提供的完整方法(占位符)如下:
Type | Method |
---|---|
Basic | boolean, natural, integer, float, character, string, range, |
Date | date ,time, datetime, now |
Image | image, dataImage |
Color | color, hex, rgb, rgba, hsl |
Text | paragraph, sentence, word, title, cparagraph, csentence, cword, ctitle |
Name | first, last, name, cfirst, clast, cname |
Web | url, domain, email, ip, tld,protocol |
Address | region ,province, city, county |
Helper | capitalize, upper, lower, pick, shuffle,zip |
Miscellaneous | guid, id,increment |
Mock.Random.extend |
Mock.Random 扩展方法,然后在数据模板中通过 @扩展方法 引用。例如:
const Mock = require("mockjs");
var Random = Mock.Random
Random.extend({
product:function (index){
const types = ['products', 'industryApp', 'solution', 'experts'];
if(typeof index == 'number'){
if(index>=types.length){
index=types.length-1
}
return this.pick(types[index])
}
return this.pick(types)
}
})
Random.product()
Random.product(5)
console.log(Mock.mock('@product'));
Mock.setup( settings ) |
配置拦截 Ajax 请求时的行为。目前支持的配置项有:timeout
settings,必选,配置项集合
timeout,可选,指定被拦截的 Ajax 请求的响应时间,单位是毫秒。值可以是正整数,例如 400,表示 400 毫秒 后才会返回响应内容;也可以是横杠 ‘-’ 风格的字符串,例如 ‘200-600’,表示响应时间介于 200 和 600 毫秒之间。默认值是’10-100’。
Mock.setup({
timeout: 400
})
Mock.setup({
timeout: '200-600'
})
目前,接口 Mock.setup( settings ) 仅用于配置 Ajax 请求,将来可能用于配置 Mock 的其他行为。
Mock.mock |
Mock.js 通过覆盖和模拟原生 XMLHttpRequest 的行为来拦截 Ajax 请求
rURL(Redirective Uniform Resource Locator)【可选】:重定向统一资源定位符,表示需要拦截的 URL,可以是 URL 字符串或 URL 正则。
rtype【可选】:表示需要拦截的 Ajax 请求类型。例如 GET、POST、PUT、DELETE 等。
template【可选】:表示数据模板,可以是对象或字符串。
function(options)【可选】:表示用于生成响应数据的函数。
Mock.mock( template ) |
根据数据模板生成模拟数据
const Mock = require("mockjs");
const template={
'name':'@first',
'age':'@integer(20, 30)',
'city':'@city(true)'
}
let data= Mock.mock(template);
console.log(data);
//{ name: 'Linda', age: 27, city: '台湾 嘉义县' }
Mock.mock( rURL, template) |
使用Mock拦截请求,当拦截到匹配 rURL 的请求时,将根据数据模板 template 生成模拟数据,并作为响应数据返回。
// Mock.mock(rurl, template)
Mock.mock(/\.json/, {
'list|1-10': [{
'id|+1': 1,//属性 id 是一个自增数,起始值为 1,每次增 1
'email': '@EMAIL'//随机邮箱地址
}]
})
$.ajax({
url: 'hello.json',
dataType: 'json'
}).done(function(data, status, jqXHR){
$(''
).text(JSON.stringify(data, null, 4))
.appendTo('body')
})
Mock.mock( rURL, function( options ) ) |
当拦截到匹配 rurl 的请求时,函数 function(options) 将被执行,并把执行结果作为响应数据返回。
// Mock.mock(rurl, function(options))
Mock.mock(/\.json/, function(options) {
return options
})
$.ajax({
url: 'hello.json',
dataType: 'json'
}).done(function(data, status, jqXHR) {
$(''
).text(JSON.stringify(data, null, 4))
.appendTo('body')
})
$.ajax({
url: 'hello.json',
dataType: 'json',
data: {
foo: 1,
bar: 2,
faz: 3
}
}).done(function(data, status, jqXHR) {
$(''
).text(JSON.stringify(data, null, 4))
.appendTo('body')
})
$.ajax({
url: 'hello.json',
type: 'post',
dataType: 'json',
data: {
foo: 1,
bar: 2,
faz: 3
}
}).done(function(data, status, jqXHR) {
$(''
).text(JSON.stringify(data, null, 4))
.appendTo('body')
})
Mock.mock( rURL, rtype, template) |
当拦截到匹配 rurl 和 rtype 的请求时,将根据数据模板 template 生成模拟数据,并作为响应数据返回。
// Mock.mock( rurl, rtype, template )
Mock.mock(/\.json/, 'get', {
type: 'get'
})
Mock.mock(/\.json/, 'post', {
type: 'post'
})
$.ajax({
url: 'hello.json',
type: 'get',
dataType: 'json'
}).done(function (data, status, jqXHR) {
$(''
).text(JSON.stringify(data, null, 4))
.appendTo('body')
})
$.ajax({
url: 'hello.json',
type: 'post',
dataType: 'json'
}).done(function (data, status, jqXHR) {
$(''
).text(JSON.stringify(data, null, 4))
.appendTo('body')
})
Mock.mock( rURL, rtype, function( options )) |
当拦截到匹配 rurl 和 rtype 的请求时,函数 function(options) 将被执行,并把执行结果作为响应数据返回。
// Mock.mock( rurl, rtype, function(options) )
Mock.mock(/\.json/, 'get', function(options) {
return options.type
})
Mock.mock(/\.json/, 'post', function(options) {
return options.type
})
$.ajax({
url: 'hello.json',
type: 'get',
dataType: 'json'
}).done(function (data, status, jqXHR) {
$(''
).text(JSON.stringify(data, null, 4))
.appendTo('body')
})
$.ajax({
url: 'hello.json',
type: 'post',
dataType: 'json'
}).done(function (data, status, jqXHR) {
$(''
).text(JSON.stringify(data, null, 4))
.appendTo('body')
})
react中使用axios + mockjs模拟后台数据 |
正常形式 |
1.初始化项目 |
//使用react脚手架搭建新项目
npx create-react-app react-axios-mock
cd react-axios-mock
2.安装依赖 |
npm i axios
npm i mockjs -D
3.配置 axios |
request.js
import axios from "axios";
const Axios = axios.create();
Axios.defaults.timeout = 2000;
// 添加请求拦截器
Axios.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
Axios.interceptors.response.use(
function (response) {
// 对响应数据做点什么
return response;
},
function (error) {
// 对响应错误做点什么
return Promise.reject(error);
}
);
export default Axios;
4.配置 mock |
mockUserInfo.js
import Mock from 'mockjs'
const Random=Mock.Random
Mock.setup({
timeout: '500'
})
function createUsers() {
let user = [];
while (true) {
user.push({
name: Random.first(),
sex: Random.boolean(1, 1, true) ? "male" : "female",
age: Random.integer(20, 50),
});
if (user.length === 2) break;
}
return user;
}
const users=[
{
url:'/getUsers',
type:'get',
response:()=>{
return Mock.mock({
'users|3-5':createUsers()
})
}
},
{
url:'/addUser',
type:'post',
response:(data)=>{
return Mock.mock({
data
})
}
}
]
export default users;
mockIndex.js
import Mock from 'mockjs'
import user from './mockUserInfo'
const mocks = [
...user
]
// mock请求方法放在这里统一处理,1是简便写法,2是如果请求路径需要加统一前缀或域名,可以在这里处理
for (const i of mocks) {
Mock.mock(i.url, i.type, i.response)
}
5.后台接口请求路径配置文件 |
userService.js
import request from './request'
export function getUsers(){
return request({
url:'/getUsers',
method:'get'
})
}
export function addUser(data){
return request({
url:'/addUser',
method:'post',
data
})
}
6.引入mock,在项目的最外层目录index.js里引入,直接引入就可以 |
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './mockIndex'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
7.组件中使用 |
App.js
import React,{
useState} from 'react'
import {
getUsers} from './userService'
function App() {
const [users,setUsers]=useState([]);
const getAllUsers=async()=>{
const res=await getUsers();
if(res.status===200)
setUsers(res.data.users)
}
return (
<>
<button onClick={
getAllUsers}>点击获取最新用户信息</button>
{
users.map((it,index)=>(
<p key={
index}>姓名:{
it.name} 性别:{
it.sex} 年龄:{
it.age}</p>
))}
</>
);
}
export default App;
8.启动项目 |
npm run start
react-axios |
适用于react框架的Axios 组件, 具有 child function callback.
在render阶段进行异步请求。
在上个例子基础上,
npm i react-axios
修改App.js
import React, {
useState } from "react";
import {
Request } from "react-axios";
import axios from "axios";
function App() {
const [users, setUsers] = useState([]);
return (
<>
<Request
instance={
axios.create({
})} /* custom instance of axios - optional */
method="get" /* get, delete, head, post, put and patch - required */
url="/getUsers" /* url endpoint to be requested - required */
onSuccess={
(response) => {
setUsers(response.data.users);
}} /* called on success of axios request - optional */
/>
{
users.map((it, index) => (
<p key={
index}>
姓名:{
it.name} 性别:{
it.sex} 年龄:{
it.age}
</p>
))}
</>
);
}
export default App;
页面渲染的时候就会去异步加载
更多关于react-axios知识,点此查看
=========================================================================================
行文至此,若有不足,还望指出,多多支持。
=========================================================================================
参考文档:
axios中文文档|axios中文网
react中使用axios + mockjs模拟后台数据
Mock.mock()