请求反馈原则指,请求返回的结果界面提示应当有哪部分(Axios封装 | store | .vue)处理
Axios封装
import Vue from "vue"
import axios from "axios"
import qs from "qs"
// import store from "@/store/index"
import router from "@/router/index"
//全局配置
if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = '/api'
} else if (process.env.NODE_ENV === 'production') {
axios.defaults.baseURL = ''
}
axios.defaults.timeout = 10000
// 请求头信息是为post请求设置
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
// 全局变量名
let loadingInstance = null
//状态码信息
const codeMessage = {
200: "服务器成功返回请求信息",
201: "新建或修改数据成功",
202: "一个请求已经进入后台排队(异步任务)",
204: "删除时局成功",
400: "发出的请求有错误,服务器没有进行操作",
401: "未登录或登录超市",
403: "没有权限进行此操作",
404: "访问的资源不存在",
406: "请求的格式不可得",
410: "请求的资源被永久删除,且不会在得到",
422: "当创建一个对象时,发生一个验证错误",
500: "服务期发生错误,请检查服务器",
502: "网关错误",
503: "服务器不可用,服务器暂时过载或维护",
504: "网管超时"
}
//创建axios实例
const axiosInstance = axios.create();
//发起请求前
axiosInstance.interceptors.request.use(
function (config) {
if (config.params.LOADING) {
loadingInstance = Vue.prototype.$loading({
lock: true,
text: '处理中...',
spinner: "el-icon-loading",
background: "rgba(0,0,0,0.7)"
})
}
return config
},
function (error) {
Vue.prototype.$message({
message: "加载超时",
type: "worning"
})
return Promise.reject(error)
}
)
//发起请求后
axiosInstance.interceptors.response.use(
function (res) {
loadingInstance && loadingInstance.close()
if (res.status >= 200 && res.status < 300) {
//switch内的语句是为特定项目服务的,你当然不必这样定义;实际上我认为统一交给状态码标识状态比较好
switch (res.data.reply) {
case 'ok':
if (res.data.result == -2) {
Vue.prototype.$message({
type: "error",
message: "数据异常"
})
} else {
res.config.params.SHOW_MESSAGE_SUCCESS && Vue.prototype.$message({
type: "success",
message: "提交成功"
})
}
break;
case 'userExist':
Vue.prototype.$message({
type: "error",
message: "用户已经存在"
})
break;
case 'invalidArea':
Vue.prototype.$message({
type: "error",
message: "您所选择的区域无效"
})
break;
case 'unknownError':
Vue.prototype.$message({
type: "error",
message: "未知错误"
})
break;
case 'unLogin':
Vue.prototype.$message({
type: "error",
message: "未登录"
})
window.setTimeout(function () { router.push("/login") }, 2500)
break;
case 'accessDenied':
Vue.prototype.$message({
type: "error",
message: "没有此操作权限"
})
break;
case 'invalidParameter':
Vue.prototype.$message({
type: "error",
message: "无效参数"
})
break;
case 'failed':
Vue.prototype.$message({
type: "error",
message: "提交失败"
})
break;
}
}
return res
},
function (error) {
loadingInstance && loadingInstance.close()
//请求配置发生错误
if (error) {
if (error.response) {
const status = error.response.status;
const errorText = codeMessage[status] || error.response.statusText;
//提示错误信息
Vue.prototype.$message({
message: errorText,
type: 'error'
});
//错误状态处理
if (status === 401) {
router.push("/login")
}
else if (status === 403) {
Vue.prototype.$message({
message: "没有此操作权限",
type: "error"
})
}
else if (404 <= status && status < 422) {
router.push("./404")
}
}
}
return Promise.reject(error)
}
)
export function get({
url,
data = {},
params = {}
}) {
return new Promise(function (resolve, reject) {
axiosInstance.get(url + qs.stringify(data), {
params
}).then(function (res) {
resolve(res.data.result || res.data)
}).catch(err => {
reject(err)
})
})
}
// post请求
export function post({
url,
data = {},
params = {}
}) {
return new Promise((resolve, reject) => {
axiosInstance({
url,
method: 'post',
// transformRequest: [function (data) {
// let ret = ''
// for (let it in data) {
// ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
// }
// return ret
// }],
// 发送的数据
data: data,
// url参数
params: params
}).then(res => {
console.log('res', res, res.data.result || res.data)
//数据有些放在res.data.result,有些放在res.data。希望后台设计规范起来
resolve(res.data.result || res.data)
}).catch(err => {
reject(err)
})
})
}
请求反馈原则
能统一处理当然是最好的,所以请求反馈处理的优先顺序是Axios封装 > store>.vue
那什么时候在store文件处理呢?下面一个例子。注意看actions-login
/**
* 用户登录
*/
import { userLogin, getLoginInfo, logout } from '@/api/api.js'
import Vue from 'vue'
export default {
namespaced: true,
state: function () {
return {
loginInfo: {
name: '',
pass: '',
verify: '',
type: 1, /*1是政府账户 2是企业账户 */
},
loginStatus: -4/**0-成功 -1 -2 -3 -4 */
}
},
mutations:
{
setName: function ({ loginInfo }, { name }) {
loginInfo.name = name
},
setPass: function ({ loginInfo }, { pass }) {
loginInfo.name = pass
},
setVerify: function ({ loginInfo }, { verify }) {
loginInfo.verify = verify
},
setType: function ({ loginInfo }, { type }) {
loginInfo.verify = type
},
setStatus: function (state, { status }) {
state.loginStatus = status
},
reset: function (state) {
state.loginStatus = -4;
const { loginInfo } = state;
loginInfo.name = '';
loginInfo.pass = '';
loginInfo.verify = '';
}
},
actions: {
login: async function ({ state, commit }, { callback }) {
const res = await userLogin(state.loginInfo)
const v = res.code
commit('setStatus', { status: v })
if (v == 0) {
Vue.prototype.$message({
type: "success",
message: "登录成功"
});
} else {
let msg =
v == -1 ? "验证码错误" : v == -2 ? "用户名或密码错误" : "用户不存在";
Vue.prototype.$message({
type: "error",
message: msg
});
}
callback()
},
logout: async function ({ commit }, { router }) {
await logout()
commit('reset')
router.push('login')
},
init: async function ({ commit }) {
const loginInfo = await getLoginInfo()
const { loginName, loginType/**cityId,provinceId */ } = loginInfo
commit('setName', { name: loginName })
commit('setStatus', { status: (loginType == 1 ? 0 : -1) })
}
}
}
像这种无需所有的请求结果都经过这一条过滤,只在局部需要过滤的情况,放在store中处理。
其它原因不方便在store过滤处理的情况在放到.vue文件中