正文
虽然vue中axios的使用已经十分方便,但是实际我们的日常操作中可能为了接口的规则一致,来创建一个统一管理的全局方法达到简化操作.而且在实际接口对接中,我们大多都需要对请求和响应进行拦截来进行token以及回调状态码的处理.那么我基于自己的需求简单分装了一下.(之前很少接触vue,主要用的ng和react,这次新项目想用vue来弄,熟悉一下vue的一些新特性和方法,有啥不对的,欢迎大家批评指正)
前提:
熟悉前端ts, node等等.
1. 安装axios
2. 拦截器及全局方法编写
一个http.ts文件进行自己http逻辑的封装,为了代码分离,我同时创建interceptors.ts文件进行拦截器逻辑,放在一起也行.
interceptors.ts
(拦截器,进行请求和响应拦截并进行部分逻辑处理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| import axios from 'axios'; import {message} from 'ant-design-vue';
export class Interceptors { public instance: any;
constructor() { this.instance = axios.create({timeout: 1000 * 12}); this.initInterceptors(); } public getInterceptors() { return this.instance; }
public initInterceptors() { this.instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
this.instance.interceptors.request.use( (config) => { if (config.headers.isJwt) { const token = localStorage.getItem('id_token'); if (token) { config.headers.Authorization = 'Bearer ' + token; } } return config; }, (error) => { console.log(error); }, );
this.instance.interceptors.response.use( (res) => { if (res.headers.authorization) { localStorage.setItem('id_token', res.headers.authorization); } else { if (res.data && res.data.token) { localStorage.setItem('id_token', res.data.token); } }
if (res.status === 200) { return Promise.resolve(res.data); } else { this.errorHandle(res); return Promise.reject(res.data); } }, (error) => { const {response} = error; if (response) { this.errorHandle(response); return Promise.reject(response.data); } else { message.warn('网络连接异常,请稍后再试!'); } }); }
private errorHandle(res: any) { switch (res.status) { case 401: break; case 403: break; case 404: message.warn('请求的资源不存在'); break; default: message.warn('连接错误'); } } }
|
http.ts
(http封装,自己根据实际情况处理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
import {Interceptors} from '@/service/interceptors'; import {message, Modal} from 'ant-design-vue'; import router from '../router';
export class HttpService { public axios: any; public modal: any;
constructor() { this.axios = new Interceptors().getInterceptors(); }
public getData(params: object, jwt: boolean, modulename: string, operation: string, flag: string, verson = '1.0.0', service = 'services') {
const url = service + '/' + verson + '/' + modulename + '/' + operation; const body = { parameter: { data: params, tag: flag, }, };
return new Promise((resolve, reject) => { this.axios.get(url, { params: body, headers: {isJwt: jwt}, }).then((res) => { this.resultHandle(res, resolve); }).catch((err) => { reject(err.message); }); });
}
public postData(params: object, jwt: boolean, modulename: string, operation: string, flag: string, verson = '1.0.0', service = 'services') { const url = service + '/' + verson + '/' + modulename + '/' + operation; const body = { data: params, tag: flag, }; return new Promise((resolve, reject) => { this.axios.post(url, body, { headers: {isJwt: jwt}, }).then((res) => { this.resultHandle(res, resolve); }).catch((err) => { reject(err.message); }); });
}
public resultHandle(res: any, resolve) { if (res.status > 0) { resolve(res.data); } else { this.errorHandle(res); } }
public errorHandle(res: any) { message.warn(res.msg); switch (res.status) { case -102: break; case -152: break; default: } }
}
|
3. 挂载
我们定义好拦截器,那么就得把他挂载全局,能让我们方便使用.
main.ts
1 2 3 4 5 6 7 8 9 10 11 12
| import Vue from 'vue'; import App from './App.vue'; import HighchartsVue from 'highcharts-vue';
Vue.config.productionTip = false;
Vue.prototype.$httpService = new HttpService();
new Vue({ router, render: (h) => h(App), }).$mount('#app');
|
4. ts桥连(也不知道怎么称呼,自己从ng时就一直这么称呼)
行完上一步一定会发现报错啊,$httpService是个啥,不存在啊,这是因为ts的特性导致.
main.ts的同级目录创建一个xx.d.ts文件.
1 2 3 4 5 6 7
| import {HttpService} from './service/http'; declare module 'vue/types/vue' { interface Vue { $httpService: HttpService; } }
|
5. 使用
在其它组件中使用,直接用this调用,不用再去引用,但是小心在某个this指向变了的回调中使用时找不到,至于怎么怎么解决应该都懂.
1 2 3 4 5
| this.$httpService.postData({}, true, 'execute', 'xxx', 'tag').then((result) => { }, (error) => { console.log(error); });
|
最后:
这是在ts下的封装,js的话更简单点,甚至应该会更简单点(会少一些步骤,网上教程应该很多).挂载http工具的方式平时也适合我们定义全局工具类或者服务.