开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情
在实际工作中,为了用户体验,通常会在接口返回数据和渲染这个时间点添加一个加载动画,告诉用户数据正在路上,如果每次都单独写一个,太过繁琐和麻烦,所以就用到了拦截器,不仅可以添加loading,还可以添加token,验证用户登录。
一、先创建request.js
// 引入依赖
import axios from 'axios';
// 看实际需要
import { Message, Loading, MessageBox } from 'element-ui';
二、创建axios实例
const request = axios.create({
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
timeout: 500000, // 请求超时时间
});
三、请求拦截器
发送请求之前运行一般会判断是否有token,如果token存在则在请求头加上这个token。服务端会判断我这个token是否过期。可以设置加载全局loading。
// loading函数
// 记录请求次数
let needLoadingRequestCount = 0;
let loading;
function startLoading() {
loading = Loading.service({
lock: true,
text: '加载中……',
background: 'rgba(0, 0, 0, 0.5)',
});
}
function endLoading() {
// 延迟500ms,防止网速特快加载中画面一闪而过
setTimeout(function () {
if (loading) loading.close();
}, 500);
}
// 打开loading
function showFullScreenLoading() {
if (needLoadingRequestCount === 0) {
startLoading();
}
needLoadingRequestCount++;
}
// 关闭loading
function tryHideFullScreenLoading() {
if (needLoadingRequestCount <= 0) return;
needLoadingRequestCount--;
if (needLoadingRequestCount === 0) {
endLoading();
}
}
// request拦截器
request.interceptors.request.use(
(config) => {
// 打开loading
showFullScreenLoading();
const token = localStorage.getItem('token');
if (token) {
// 判断是否存在token,如果存在的话,则每个http header都加上token
config.headers.authorization = token; //请求头加上token
}
return config;
},
(error) => {
// 关闭loading
tryHideFullScreenLoading();
// Do something with request error
Promise.reject(error);
},
);
四、响应拦截器
对服务端返回的数据进行处理,存储token,错误处理、登录、登录失效路由跳转、关闭全局loading等。
// respone拦截器
request.interceptors.response.use(
(response) => {
// 关闭loading
tryHideFullScreenLoading();
const res = response.data;
if (!res.success) {
// B002:Token 过期了;
if (res.code === 'B002') {
// 最后一次出弹框
if (needLoadingRequestCount === 0) {
MessageBox.confirm(
`你已被登出,可以取消继续留在该页面,
或者重新登录, 确定登出`,
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning',
},
).then(() => {
// 返回登录页
// ...做些事情
// 为了重新实例化vue-router对象 避免bug
location.reload();
});
}
} else {
Message({
message: res.msg,
type: 'error',
});
}
return Promise.reject(res.msg || 'error');
} else {
// 如果存在token
let token = response.headers.authorization;
if (token) {
localStorage.setItem('token', token);
}
return response.data;
}
},
(error) => {
// 关闭loading
tryHideFullScreenLoading();
Message({
message: error,
type: 'error',
duration: 2000,
});
return Promise.reject(error);
},
);
五、导出实例
export default request;
六、创建api.js
import request from './request';
/* 验证登陆 */
export function login(data) {
return request.post('/login', data);
}