Axios封装
在vue项目中,我们经常使用的http请求库为axios,为了不在每个组件上都重新引入axios库,所以将axios封装起来使用,能较减少代码复杂度,易于维护。
request.js文件
引入相关使用的包
引入router是有些判断需要跳转重定向页面
我是使用element-ui框架的,使用message来提示信息
import axios from 'axios';
import router from '../router';
import { Message } from 'element-ui';
/*
* 提示函数
* 显示错误提示,1秒后消失
* */
const tip = msg =>{
Message({
type: 'error',
message: msg,
duration: 1000
})
}
未登录时跳转登录页
/*
* 跳转登录页
* 携带当前页面路由,以期在登录页面完成登录后返回当前页面
* */
const toLogin = () => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
}
请求失败后的错误处理
/*
* 请求失败后的错误统一处理
* @param { Number } status 请求失败的状态码
* */
const errorHandle = (status, other) => {
// 状态码判断
switch (status) {
// 401: 未登录状态,跳转登录页
case 401:
toLogin();
break
// 403: token过期
// 清除token并跳转登录页
case 403:
tip('登录过期,请重新登录');
localStoragere.removeItem('token');
setTimeout(()=> {
toLogin();
},1000);
break;
// 404请求不存在
tip('请求的资源不存在');
break;
default:
console.log(other)
}
}
初始化实例
// 创建axios实例
const service = axios.create({
timeout: 20*1000
});
// 设置post请求头
service.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
使用拦截器,处理通用逻辑
/*
* 请求拦截器
* */
service.interceptors.request.use(
config => {
return config;
},
error => {
console.log(error);
return Promise.reject();
}
);
/*
* 响应拦截器
* */
service.interceptors.response.use(
response => {
if (response.status === 200) {
return response.data;
} else {
Promise.reject();
}
},
error => {
errorHandle(error.response.status)
console.log(error);
return Promise.reject();
}
);
输出axios实例
export default service;
全部代码
import axios from 'axios';
import router from '../router';
import { Message } from 'element-ui';
// Message.error("error")
/*
* 提示函数
* 显示错误提示,1秒后消失
* */
const tip = msg =>{
Message({
type: 'error',
message: msg,
duration: 1000
})
}
/*
* 跳转登录页
* 携带当前页面路由,以期在登录页面完成登录后返回当前页面
* */
const toLogin = () => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
}
/*
* 请求失败后的错误统一处理
* @param { Number } status 请求失败的状态码
* */
const errorHandle = (status, other) => {
// 状态码判断
switch (status) {
// 401: 未登录状态,跳转登录页
case 401:
toLogin();
break
// 403: token过期
// 清除token并跳转登录页
case 403:
tip('登录过期,请重新登录');
localStoragere.removeItem('token');
setTimeout(()=> {
toLogin();
},1000);
break;
// 404请求不存在
tip('请求的资源不存在');
break;
default:
console.log(other)
}
}
// 创建axios实例
const service = axios.create({
timeout: 20*1000
});
// 设置post请求头
service.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
/*
* 请求拦截器
* */
service.interceptors.request.use(
config => {
return config;
},
error => {
console.log(error);
return Promise.reject();
}
);
/*
* 响应拦截器
* */
service.interceptors.response.use(
response => {
if (response.status === 200) {
return response.data;
} else {
Promise.reject();
}
},
error => {
errorHandle(error.response.status)
console.log(error);
return Promise.reject();
}
);
export default service;
api/index.js
引入要使用的包
…/utils/request 为上面所封装的axios初始化
…/utils/data/base 为服务器基本地址
import axios from '../utils/request';
import base from '../utils/data/base';
import qs from 'qs';
import router from '../router';
封装公共函数request()
api:String 接口地址
params:Object 请求参数
method:String 请求方法
function request(api,params,method) {
let token =null;
let bearer = null;
if(localStorage.getItem("zq-token")){
let storage = JSON.parse(localStorage.getItem("zq-token"));
token = storage.token;
// bearer = storage.token_type;
}
let config = {
url: api,
method: method,
baseURL: base.url,
headers: {
"Authorization": "bearer "+ token
}
}
if(method === "post" || method === "delete" || method === "put"){
config['data'] = params;
}else {
config['params'] = params;
}
return axios.request(config).then(res => {
if(res.code == 401){
localStorage.removeItem('zq-token');
router.push('/login');
return {code:401, msg: "登录过期,请重新登录"};
}
return res;
})
}
功能模块接口集合,如果有多个功能模块,可以分文件
//登录与权限
const Certification = {
login (params){
return request('/admins/login',params, 'post');
},
logout(){
return request('/admins/logout',{},'post');
},
changePass(params) {
return request('/admins/update/pwd', params, 'put')
}
}
输出功能模块对象,如果多个模块,可以输出request函数,然后模块再整理成一个总模块
export default {
Certification
};
main.js
在main.js中把api对象挂载在全局变量$api中
import Vue from 'vue'
import api from "./api"
Vue.prototype.$api = api
页面组件使用api.Certification.login(params).then(res => {})
Certification是api/index.js中输出的对象,表示一个功能模块,里面包含有多个方法,login为其中的方法。
export default {
name: "Test",
data(){
return {
}
},
created() {
this.$api.Certification.login(params).then(res => {
// 接口返回数据的逻辑处理
})
},
}
以上是我总结的使用方法,只是个人意见,以此作为记录,如有错误,欢迎纠正。