封装axios请求
1、为什么要封装axios
封装axios,对错误信息进行统一处理,能提高代码简洁性,规范代码
2、封装步骤
2.1 创建文件
首先在utils文件夹下新建request.js文件,内容如下。要确保项目已经安装了axios,和element-ui
import store from '@/store'
import { getToken } from '@/utils/local'
import axios from 'axios'
import { Message } from 'element-ui'
//生产环境请求接口地址
if (process.env.NODE_ENV === 'production') {
// window.config.userCenter = `${window.location.origin}:8080`
window.config.serveIp = `${window.location.origin}/api`
window.config.serveUrl = `${window.location.origin}/api`
}
// create an axios instance
const service = axios.create({
// baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
baseURL: window.config.serveUrl,
timeout: 60000 // request timeout
})
const pending = []
const cancelToekn = axios.CancelToken
let removeP = false
const removePending = (config, isAll) => {
for (let i = 0; i < pending.length; i++) {
if (isAll) {
pending[i].fun()
pending.splice(i, 1)
i--
} else {
if (pending[i].name === config.url + JSON.stringify(config.data) + '&' + config.method) {
pending[i].fun()
pending.splice(i, 1)
break
}
}
}
}
// request interceptor
service.interceptors.request.use(
config => {
// 在HTTP请求前取消前面的所有请求
removeP = config.removeP
if (config.removeP) removePending(config, true)
// 记录本次HTTP请求
// eslint-disable-next-line new-cap
config.cancelToken = new cancelToekn((c) => {
pending.push({
name: config.url + JSON.stringify(config.data) + '&' + config.method,
fun: c
})
})
// do something before request is sent
// 请求头添加token
if (getToken()) {
config.headers['Token'] = getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
if (response.status !== 200) {
Message.error(response.data.message)
} else {
return response.data
}
},
error => {
if (error.response) {
const { response: { status, data: { msg, code }}} = error
const reloadCode = [1106, 1107, 1108]
const waringCode =[1408]
switch (status) {
case 400:
Message.error(msg)
break
case 401:
// 返回 401 清除token信息并跳转到登录页面
if (reloadCode.includes(code)) {
setTimeout(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
}, 1000)
}
Message.error(msg)
break
case 403:
Message.error(msg)
break
case 404:
if(waringCode.includes(code)){
Message.warning(msg)
break
}
Message.error(msg)
break
case 408:
error.message = '请求超时'
break
case 422:
Message.error('参数错误')
break
case 500:
error.message = '服务器内部错误'
break
case 501:
error.message = '服务未实现'
break
case 502:
// 连接服务器失败
Message.error('服务器内部错误')
setTimeout(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
}, 500)
Message.error('服务器内部错误')
error.message = '网关错误'
break
case 503:
error.message = '服务不可用'
break
case 504:
error.message = '网关超时'
break
case 505:
error.message = 'HTTP版本不受支持'
break
default:
error.message = '连接服务器异常'
}
return error
} else {
if (removeP) {
return
}
error.message = '连接服务器失败'
Message.error('连接服务器失败')
console.log(error.message)
}
}
)
export default service
2.2 使用封装的request
首先对接口进行分类,例如商品接口,src下新建api文件夹,新建goods.js
首先要引入封装的request,然后导出
// 引入封装的request
import request from '@/utils/request'
// 获取商品列表
export function getGoodsList(data) {
return request({
url: '/goods/list',
method: 'get',
data
})
}
2.3 在组件中使用
// 首先按需引入使用的接口
import { getGoodsList } from "@/api/goods.js"
接口返回的是promise格式,可以用async await 或者.then.catch解析
// 然后在方法中直接使用
created() {
this.getTableList()
},
methods: {
getTableList() {
let data= {
page: 1,
pagesize: 20
}
// 接口返回的时promise
getGoodsList(data).then(res=>{
if(res.code == 200) {
this.tableData = res.data
}
}).catch(error => {
console.log(error);
})
}