前几年有一个项目需要在还没有开发接口的情况下,需要前端独立开发,review,或者给客户展示demo,都需要模拟有接口可进行操作的环境,可以使用mock来完成,考虑换种方式完成就自己构建json模拟数据,模拟api.js,这里对mock的方式不做阐述,以登录功能为例说明:
具体部署如下:
一、模拟接口返回数据
需要用到vuex,安装:
npm i vuex -S or yarn add vuex -S
二、模拟api接口并构造返回数据
1、模拟api,首先需要用到axios,安装axios
npm i axios -S or yarn add axios -S
2、需要使用vuex构造存储json模拟接口返回的数据,安装vuex
npm i vuex -S or yarn add vuex -S
3、构造json模拟数据
在src\store下新建文件xxx.js
代码如下:
const user = {
state: {
loginCacheData: { "msg": "操作成功", "code": 200, "token": "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjJjYjYyNzkzLTQ1Y2UtNGY3YS04ZmNjLTE4M2E4YWZkOTE3ZiJ9.kD1ScvEHuDJVTMl1KPUf3coYaN8s42T22bPE1dLXxzZMb7zZr0IkooivAk11aEQYb5q0ExW6n066Tf6AzU7vbQ" },
getInfoCacheData: { "msg": "操作成功", "code": 200, "permissions": ["*:*:*"], "roles": ["admin"], "user": { "searchValue": null, "createBy": "admin", "createTime": "2018-03-16 11:33:00", "updateBy": "ry", "updateTime": "2020-11-18 11:29:03", "remark": "管理员", "params": {}, "userId": 1, "deptId": 100, "userName": "admin", "nickName": "管理系统", "email": "[email protected]", "phonenumber": "15888888888", "sex": "男", "avatar": "/profile/avatar/2021/02/26/0a499c87-6391-4021-9452-ab0e2e8aaf6a.jpeg", "salt": null, "status": "0", "delFlag": "0", "loginIp": "127.0.0.1", "loginDate": "2018-03-16T11:33:00.000+0800", "dept": { "searchValue": null, "createBy": null, "createTime": null, "updateBy": null, "updateTime": null, "remark": null, "params": {}, "deptId": 100, "parentId": null, "ancestors": null, "deptName": null, "orderNum": null, "leader": null, "phone": null, "email": null, "status": null, "delFlag": null, "parentName": null, "deptType": null, "children": [], "professionId": null }, "roles": [], "roleIds": null, "postIds": null, "idCardNo": "370521197810182817", "idCardFront": "http://xxx/1605670142299.jpg", "idCardBack": "http://xxx/1605670146726.jpg", "userGroup": "1", "deptName": null, "pName": null, "cTime": null, "aStatus": null, "professionId": null, "dateTime": null, "dateTimeEnd": null, "code": null, "classId": null, "className": null, "authentication": null, "address": null, "admin": true } },
},
}
三、模拟数据接口调用
src\api下新建cacheApi文件夹,新建login.js文件,代码如下:
import request from '@/utils/request'
import store from '@/store'
// 登录方法
export function login(username, password, code, uuid) {
const data = {
username,
password,
code,
uuid
}
return new Promise(resolve => {
const response=store.state.user.loginCacheData
resolve(response)
})
}
/utils/request.js是对axios进行了封装,加入了拦截器,关于token处理相关的依赖,根据自己项目情况开发,每个项目里应该都有,不做详解了,代码如下:
import axios from 'axios'
import { Notification, MessageBox, Message ,Loading} from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000
})
let loading;
// request拦截器
service.interceptors.request.use(config => {
loading = Loading.service({
lock: true,
text: '努力加载中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
loading.close();
// loading.close();
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const message = errorCode[code] || res.data.msg || errorCode['default']
if (code === 401) {
MessageBox.confirm(
'登录状态已过期,您可以继续留在该页面,或者重新登录',
'系统提示',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
store.dispatch('LogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
})
} else if (code === 500) {
Message({
message: message,
type: 'error'
})
return Promise.reject(new Error(message))
} else if (code !== 200) {
Notification.error({
title: message
})
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
具体调用接口的位置。代码如下(根据自己项目的情况调整):
import { login} from 'unkApi/login'
...
// 登录
Login({
commit
}, userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
setToken(res.token)
commit('SET_TOKEN', res.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
四、项目配置
在web.config添加一个是否采用离线缓存的开关,isoffline为true时采用离线缓存,这时就src\cacheApi里的接口调用,不走src\Api下的接口调用了:
...
const isOffline = true
const apiSrc = isOffline === true ? '/cacheApi' : '/api'
module.exports = {
...
configureWebpack: {
name: name,
resolve: {
//extensions: ['.js', '.vue', '.json'],
alias: {
//'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
'unkApi': resolve('src')+apiSrc,
}
}
}
...
此方法完全可以用mock代替,并且mock的功能强大,还能完成更多其他的功能,项目较小并对依赖容量有要求,或者无法使用mock等其他拓展测试工具的场景可以参考一下,mock是捕获http请求后模拟接口的返回,而这种手写的方式不会发送请求,因为不走进request里面,写的比较粗糙,代码也比较老,觉得思路还可以的话,欢迎评论。