1. 安装
yarn add mockjs -D
yarn add axios
2. 编写mock入口/注册文件
// /mock/index.js
// 引入Mock
import Mock from 'mockjs'
// 为了解决与后台接口共存时,丢失cookies的问题
Mock.XHR.prototype.withCredentials = true
// 设置拦截ajax请求的相应时间
Mock.setup({ timeout: '200-600' })
const configArray = []
const registerMock = ({
url,
method = 'get',
template
}) => {
Mock.mock(new RegExp('^' + url), method, template)
}
// 遍历当前目录的mock文件
const files = require.context('./', true, /\.js$/)
files.keys().forEach(key => {
if (key === './index.js') return
files(key).default.forEach(item => {
configArray.push(item)
})
})
// 注册所有的mock服务
configArray.forEach(mockItem => {
registerMock(mockItem)
})
3. 编写模拟接口文件
// /mock/login.js
const login = {
url: '/mock/user/info',
template: {
status: 200,
message: 'success',
data: {
total: 100,
'result|3': [
{
id: '@guid',
name: '@cname', // 中文名
aliasName: '@first()', // 随机英文名
'age|20-30': 23,
'job|1': ['前端工程师', '后端工程师', 'UI工程师', '需求工程师'],
birthday: '@datetime', // 随机时间
mobile: '@mobile', //
email: '@email', // 随机email
address: '@county(true)', // 随机地址
domicile: '@city(true)', // 随机城市
'list|5': [
{
id: '@guid',
'job|1': ['前端工程师', '后端工程师', 'UI工程师', '需求工程师'],
obj: {
name: '@cname',
email: '@email'
}
}
]
}
]
}
}
}
// 前面index定义导出数组, 需要遵循index文件的规范
export default [
login
]
4. axios 封装
// /api/http.js
import Axios, { CancelToken } from 'axios'
/**
* 默认axios,配置
* @type {[type]}
*/
const http = Axios.create({
timeout: 1000 * 30
})
const cancelTokenMap = {}
const openMock = true
//
if (process.env.NODE_ENV === 'development' && openMock) {
http.defaults.baseURL = '/mock'
}
http.interceptors.request.use(config => {
config.headers.common['Content-Type'] = 'application/json;charset=UTF-8'
// cancelToken
if (config.cancelToken) {
config.cancelToken = new CancelToken(c => {
if (cancelTokenMap[config.cancelToken]) {
cancelTokenMap[config.cancelToken].push(c)
} else {
cancelTokenMap[config.cancelToken] = [c]
}
})
}
return config
})
/**
* 响应拦截器
* @param {[type]} (res) [description]
* @return {[type]} [description]
*/
http.interceptors.response.use(
res => {
const { data: { status }, config } = res
if (openMock) {
const mockUrl = config.baseURL + config.url
console.clear()
console.log(`%c Mock: ${mockUrl}`, 'font-size: 18px; color: blue')
console.log('data :', JSON.parse(JSON.stringify(res.data.data.result)))
}
if (~~status === 200) {
return Promise.resolve(res.data)
} else {
messageHandler(res, config.messageFlag)
return Promise.reject(res.data)
}
},
err => {
// 错误
return Promise.reject(err)
}
)
/**
* 中断请求
* @param id
*/
http.abort = id => {
if (cancelTokenMap[id]) {
cancelTokenMap[id].forEach(c => c())
delete cancelTokenMap[id]
}
}
const messageHandler = ({ msg }, messageFlag = true) => {
if (messageFlag) {
this.alert({ type: 'error', message: msg || '网络错误' })
}
}
export default http
5. 统一导出api
// /api/index.js
export * from './login'
// /api/login.js
export const apiGetUserInfo = () => {
return http.get('/user/info')
}
6. 使用
// main.js
import '@/mock'
// xxx.vue
import { apiGetUserInfo } from '@/api'
export default {
created() {
this.getMock()
},
methods: {
async getMock() {
const { data: { result } } = await apiGetUserInfo()
console.log(result)
}
}
}
常用的Mock-template随机函数
const commonUse = {
// 返回一个随机的布尔值。
boolean: '@boolean',
// 返回一个随机的自然数(大于等于 0 的整数)。
natural: '@natural(10, 1000)',
// 返回一个随机的整数。
integer: '@integer(10, 1000)',
// 返回一个随机的浮点数。
float: '@float(10, 1000, 0, 2)',
// 返回一个整型数组。
range: '@range(10)',
// 返回一个随机的日期字符串
date: '@date',
// 返回一个随机的日期和时间字符串。
datetime: '@datetime',
// 返回当前的日期和时间字符串。
now: '@now',
// 生成一个随机的图片地址。
image: '@image',
// 随机生成一个有吸引力的颜色,格式为 '#RRGGBB'。
color: '@color',
// 随机生成一段文本。
paragraph: '@cparagraph',
// 随机生成一句中文标题。
ctitle: '@ctitle(3, 6)',
// 随机生成一个常见的中文姓名
cname: '@cname',
// 随机生成一个邮件地址。
email: '@email',
// 随机生成一个省市区。
county: '@county',
// 随机生成一个 GUID。
guid: '@guid'
}