1.首现在项目中我们在src目录下创建一个api文件夹,在文件夹中创建两个js文件分别为api.js和http.js文件名可以自定义
2.http中对axios进行的封装,添加请求拦截和响应拦截。在请求拦截中,给请求头添加token字段,还有loading动画的开启。在响应拦截中,可以做一些loading动画的关闭,还有可以根据后端返回的状态码,做一些检验token是否有效或者过期的操作。
//在http.js中引入asiox
import axios from 'axios';//引入axios
import store from '../store/index';
import router from '../router';
//vant的toast提示组件,大家课根据自己的ui组件更改
import {Toast} from 'vant';
//创建axios实例
const service = axios.create({
baseURL:'./mock',//url = base api url + request url
withCredentials:false,//end cookies when cross-domain requests
timeout:1000*12//请求超时
})
//设置post请求头
service.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// 请求拦截器
service.interceptors.request.use(
config => {
// 不传递默认开启loading
if (!config.hideloading) {
// 请求是是否开启loading
Toast.loading({
message:'正在请求....',
forbidClick: true
})
}
// 每次发送请求之前判断vuex中是否存在token
// 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况
// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
if (store.state.token) {
config.headers.token = store.state.token;
//有些接口是 config.headers.Authorization = token
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
//响应拦截
service.interceptors.response.use(
response => {
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
// 否则的话抛出错误
Toast.clear();
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
// 服务器状态码不是2开头的的情况
// 这里可以跟你们的后台开发人员协商好统一的错误状态码
// 然后根据返回的状态码进行一些操作,例如登录过期提示,错误提示等等
// 下面列举几个常见的操作,其他需求可自行扩展
error => {
if (error.response.status) {
switch (error.response.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
break;
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
Toast({
message: '登录过期,请重新登录',
duration: 1000,
forbidClick: true
});
// 清除token
store.dispatch('FedLogOut').then(() => {
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
router.replace({
path: '/login',
query: {
redirect:router.currentRoute.fullPath
}
}) })
break;
// 404请求不存在
case 404:
Toast({
message: '网络请求不存在',
duration: 1500,
forbidClick: true
});
break;
// 其他错误,直接抛出错误提示
default:
Toast({
message: error.response.data.message,
duration: 1500,
forbidClick: true
});
}
return Promise.reject(error.response);
}else {
// 处理断网的情况
// eg:请求超时或断网时,更新state的network状态
// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
// 关于断网组件中的刷新重新获取数据,会在断网组件中说明
store.commit('changeNetwork', false);
}
});
//最后导出实例
export default service;
3.接着在api.js中做一些axios进行的api接口的封装并抛出去。
import service from './http'
import qs from './qs';//根据需求是否导入qs模块
//定义请求方法
let obj = {
getList(){
return request({
url:'/index.json',
method:'get',
params:{},
hideloading:false
})
},
goodsList(){
return request({
url:'/detail',
method:'get',
params:{goodsId},
hideloading:true
})
},
login(data){
return request({
url:'/adduser',
method:'post',
data: qs.stringify(data),//注意post提交用data参数
hideloading:true
})
}
}
export default obj;