两种方式:
第一种 mockjs + axios
,最近在 ant design pro
中看到的一种方式;
第二种是通过 node 服务
的方式,如果要想实现 热更新
,需要自己起个node服务
。
感觉第二种没有第一种用起来方便,但是第二种可以用于各个端,例如小程序端。
代码地址: https://gitee.com/yan_yi_hao/demo-mock-vue
方式一
首先在vue-cli新建一个项目,创建 src/mock/index.js 模拟请求,代码如下
import { isIE } from './util'
// 判断 vue-cli 的环境不是 prod 或者 preview 是 true 时,加载 mock 服务(这里根据自己的需求判断)
if (process.env.NODE_ENV !== 'production' || process.env.VUE_APP_PREVIEW === 'true') {
// 如果是ie就报错
if (isIE()) {
console.error('[antd-pro] ERROR: `mockjs` NOT SUPPORT `IE` PLEASE DO NOT USE IN `production` ENV.')
}
// 这里最好不要用import来引入,因为import是异步加载,require是同步加载
// (关于import的问题可以参考阮一峰的《ES入门教程》)
// 避免初始化完成之后,执行vuex actions时,下方导出的内容没有加载完毕,所以用require同步加载
const Mock = require('mockjs')
require('./services/userInfo') // 模拟userInfo接口
// 设置Mock.mock() 的延迟时间 后面要用到
Mock.setup({
timeout: 800 // setter delay time
})
console.log('[antd-pro] mock mounted')
}
然后创建 src/mock/util.js 写工具方法,代码如下
util.js
// 响应体,按照自己需要的格式
const responseBody = {
msg: '',
data: null,
code: 0
}
// 模拟生成要返回的响应体,就是给响应体body赋值
export const builder = (data, msg, code = 0, headers = {}) => {
responseBody.data = data
if (msg !== undefined && msg !== null) {
responseBody.msg = msg
}
if (code !== undefined && code !== 0) {
responseBody.code = code
responseBody._status = code
}
if (headers !== null && typeof headers === 'object' && Object.keys(headers).length > 0) {
responseBody._headers = headers
}
// responseBody.timestamp = new Date().getTime()
return responseBody
}
// 获取字符串中的query,解析url上的参数
export const getQueryParameters = (options) => {
const url = options.url
const search = url.split('?')[1]
if (!search) {
return {}
}
return JSON.parse('{"' + decodeURIComponent(search)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"') + '"}')
}
// 模拟获取请求体,获取请求体数据
export const getBody = (options) => {
return options.body && JSON.parse(options.body)
}
// 判断是否是ie浏览器,不兼容ie
export const isIE = () => {
const bw = window.navigator.userAgent
const compare = (s) => bw.indexOf(s) >= 0
const ie11 = (() => 'ActiveXObject' in window)()
return compare('MSIE') || ie11
}
创建 src/mock/services/userInfo 模拟 userInfo 接口
import Mock from 'mockjs'
import { builder, getQueryParameters } from '../util'
// Mock.mock 需要一个回调,返回值就是模拟的响应体
const userInfo = (options) => {
// 获取请求参数,可根据请求体做一些事情(例子中没用到)
const queryParameters = getQueryParameters(options)
// 生成模拟数据,可查看Mockjs文档
const data = Mock.mock({
id:'@id()',
name: '@cname()'
})
return builder(data)
}
// Mock.mock( rurl, function( options ) )
// 记录用于生成响应数据的函数。
// 当拦截到匹配 rurl 的 Ajax 请求时,函数 function(options) 将被执行,并把执行结果作为响应数据返回。
Mock.mock('/api/userInfo', 'get', userInfo )
最后一步
// 在 src/main.js 中引入
import './mock'
// App.vue 中调用接口
axios.get('/api/userInfo').then(res=>{})
到此第一种方法就完成了。
方式二,本地起node服务或是用vue-cli的node服务
依赖webpack-dev-server的功能,也就是vue.config.js中配置的devServer.before,before是本地服务启动的前置钩子。
// 通过before模拟http服务,可以抽离before方法和接口的json文件
// 项目根目录下的mock/index.js
module.exports = {
devServer: {
before(app, server, compiler) {
app.get('/api/userInfo', (req, res) => {
res.json('响应体')
})
}
}
}