vue项目中使用mock模拟后端数据
前言使用mock可以让前端不在局限于后端接口,在规定好文档格式后甚至能一次性开发完整个前端接口,大大节省了对接时间,可以说是当前前端必备的技能之一了。最近做新项目,重新搭建了下框架,想着写一篇mock的配置文章,让大家共同进步。一、npm下载插件npm install mockjs --save-dev二、创建mock文件夹1.在跟目录(src目录同级)下创建mock文件夹2.mock文件夹下新建
·
前言
使用mock可以让前端不在局限于后端接口,在规定好文档格式后甚至能一次性开发完整个前端接口,大大节省了对接时间,可以说是当前前端必备的技能之一了。最近做新项目,重新搭建了下框架,想着写一篇mock的配置文章,让大家共同进步。
一、npm下载插件
npm install mockjs --save-dev
二、创建mock文件夹
1.在跟目录(src目录同级)下创建mock文件夹
2.mock文件夹下新建index.js文件
import Mock from 'mockjs'
import { param2Obj } from '../src/utils'
import user from './user'
const mocks = [
...user
]
// for front mock
// please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event).
export function mockXHR() {
// mock patch
// https://github.com/nuysoft/Mock/issues/300
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
Mock.XHR.prototype.send = function() {
if (this.custom.xhr) {
this.custom.xhr.withCredentials = this.withCredentials || false
if (this.responseType) {
this.custom.xhr.responseType = this.responseType
}
}
this.proxy_send(...arguments)
}
function XHR2ExpressReqWrap(respond) {
return function(options) {
let result = null
if (respond instanceof Function) {
const { body, type, url } = options
// https://expressjs.com/en/4x/api.html#req
result = respond({
method: type,
body: JSON.parse(body),
query: param2Obj(url)
})
} else {
result = respond
}
return Mock.mock(result)
}
}
for (const i of mocks) {
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
}
}
// for mock server
const responseFake = (url, type, respond) => {
return {
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
type: type || 'get',
response(req, res) {
console.log('request invoke:' + req.path)
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
}
}
}
export default mocks.map(route => {
return responseFake(route.url, route.type, route.response)
})
// '../src/utils'
export function param2Obj(url) {
const search = url.split('?')[1]
if (!search) {
return {}
}
return JSON.parse(
'{"' +
decodeURIComponent(search)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"')
.replace(/\+/g, ' ') +
'"}'
)
}
3.mock文件夹下新建mock-server.js文件
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) {
let mockLastIndex
const { default: mocks } = require('./index.js')
for (const mock of mocks) {
app[mock.type](mock.url, mock.response)
mockLastIndex = app._router.stack.length
}
const mockRoutesLength = Object.keys(mocks).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
}
}
function unregisterRoutes() {
Object.keys(require.cache).forEach(i => {
if (i.includes(mockDir)) {
delete require.cache[require.resolve(i)]
}
})
}
module.exports = app => {
// es6 polyfill
require('@babel/register')
// parse app.body
// https://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
const mockRoutes = registerRoutes(app)
var mockRoutesLength = mockRoutes.mockRoutesLength
var mockStartIndex = mockRoutes.mockStartIndex
// watch files, hot reload mock server
chokidar.watch(mockDir, {
ignored: /mock-server/,
ignoreInitial: true
}).on('all', (event, path) => {
if (event === 'change' || event === 'add') {
try {
// remove mock routes stack
app._router.stack.splice(mockStartIndex, mockRoutesLength)
// clear routes cache
unregisterRoutes()
const mockRoutes = registerRoutes(app)
mockRoutesLength = mockRoutes.mockRoutesLength
mockStartIndex = mockRoutes.mockStartIndex
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
} catch (error) {
console.log(chalk.redBright(error))
}
}
})
}
4.mock文件夹下新建user.js文件
也就是在index.js中引入的模拟接口文件,这里已登陆接口为例
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
export default [
// user login
{
url: '/user/login',
type: 'post',
response: config => {
const { username } = config.body
const token = tokens[username]
// mock error
if (!token) {
return {
code: 60204,
message: 'Account and password are incorrect.'
}
}
return {
code: 20000,
data: token
}
}
}
]
5.在main.js中引入
if (process.env.NODE_ENV === 'production') {
const {
mockXHR
} = require('../mock')
mockXHR()
}
6.最后一步,也是最容易忘记的一步,在vue.config.js中写入
// webpack-devser@3.X的使用
module.exports = {
devServer: {
before: require('./mock/mock-server.js')
}
}
// webpack-devser@4.X的使用
module.exports = {
devServer: {
onBeforeSetupMiddleware: (app, server, compiler) =>{
require('./mock/mock-server.js')
}
}
}
总结
调用接口/user/login就就会执行mock的接口,返回我们写好的数据了。是不是很简单,大家快去试试吧。
mock.js官网:Mock.js
更多推荐
已为社区贡献3条内容
所有评论(0)