目的
尝试封装Axios,并集中管理接口。目的是进一步提高项目的可维护性。
思路
- 确保项目中已经安装了Axios
- 在request.js文件中导入Axios,封装后导出给api.js;
- 在api.js文件中导入request.js中封装好的请求,定制接口,随后导出;
- 在页面中使用api.js暴露出的接口。
有思路了可以首先改造项目目录,在/src文件夹新建request文件夹,同时在此创建两个文件,分别是:
- request.js (用来管理Axios请求)
-
api.js (用来管理API接口)
封装Axios请求
在request.js文件中导入axios
导入qs,暂时只知道这个是用来序列化字符串的库
有需要的话,导入轻提示UI组件 toast
导入vuex store因为拦截请求前,要验证里面的状态对象
导入路由,用于解决跳转
import axios from 'axios'
import QS from 'qs'
import { Toast } from 'vant'
import store from '@/store'
import router from '@/router'
环境配置
// 分别配置开发、调试、发布时请求的根地址
if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = ''
} else if (process.env.NODE_ENV === 'debug') {
axios.defaults.baseURL = ''
} else if (process.env.NODE_ENV === 'production') {
axios.defaults.baseURL = ''
}
请求的基本配置
// 设置链接超时时长
axios.defaults.timeout = 1000 * 5
// 设置post请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
请求的拦截
axios.interceptors.request.use(
config => {
// 请求前判断token是否存在,如果存在,再请求的header都加上token
const token = store.state.token
token && (config.headers.Authorization = token)
return config
},
error => {
return Promise.error(error)
}
)
返回的拦截
axios.interceptors.response.use(
response => {
// 如果状态200,请求成功,否则抛出错误
if (response.status === 200) {
return Promise.resolve(response)
} else {
return Promise.reject(response)
}
},
// 根据后台错误状态码进行操作
// 以下是常规操作,其他需求自行拓展
error => {
if (error.response.status) {
switch (error.response.status) {
// 401 未登录
case 401:
// 跳转到登陆页面,并携带当前页面路径
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
break
// 403 token过期
case 403:
// 做出提示
Toast({
message: '403登陆信息异常,请重新登陆'
})
// 清除本地token
localStorage.removeItem('token')
// 清除vuex中的token对象
store.commit('loginSucsess', null)
// 1秒后,跳转到登陆页面,并携带当前页面路径
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
}, 1000)
break
// 404请求不存在
case 404:
Toast({
message: '404请求不存在'
})
break
default:
// 提示信息
Toast({
message: error.response.data.message
})
}
return Promise.reject(error.response)
}
}
)
封装并导出get方法
export function get (url, params) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: params
})
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
封装并导出post方法
这里有个问题要注意,axios.get()方法和axios.post()在提交数据时参数的书写方式还是有区别的。get的第二个参数是一个对象,这个对象的params属性值是参数对象。而post的第二个参数直接就是一个参数对象。
export function post (url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
API统一管理
在api.js文件中,导入request.js中封装好的get方法
import { get } from './request.js'
把接口暴露出去
// 如果有必要,把跟地址单独处理
const baseUrl = 'https://your_api_base_url.com'
// 定义接口,然后暴露出去
export const apiName = (params) => get(baseUrl + '/your_api_adress', params)
在需要使用接口的地方
// 导入接口
import { apiName } from '@/request/api.js'
// 使用接口
apiName(params)
.then(res => {
// 成功后的操作
})
.catch(res => {
// 失败后的操作
})