整齐的api就像电路板一样,即使再复杂也能很清晰整个线路。上面说了,我们会新建一个api.js,然后在这个文件中存放我们所有的api接口。/ q A$ c9 J) s
, C; I% H6 W1 g/ m. Y 首先我们在api.js中引入我们封装的get和post方法:( M& ~! p8 \' c1 U1 [& I
- /**
- * api接口统一管理
- */
- import { get, post } from './http'
现在,例如我们有这样一个接口,是一个post请求:http://www.baiodu.com/api/v1/users/my_address/address_edit_before 我们可以在api.js中这样封装:
* `9 O6 |) p, e( P: ]3 V3 Z- export const apiAddress = p => post('api/v1/users/my_address/address_edit_before', p);
我们定义了一个apiAddress方法,这个方法有一个参数p,p是我们请求接口时携带的参数对象。而后调用了我们封装的post方法,post方法的第一个参数是我们的接口地址,第二个参数是apiAddress的p参数,即请求接口时携带的参数对象。最后通过export导出apiAddress。# W8 D# T& [. l
然后在我们的页面中可以这样调用我们的api接口:# V* {. x7 O& E/ X# d1 Q' A
6 S! v" F8 A5 h& P3 \
- import { apiAddress } from '@/request/api';// 导入我们的api接口
- export default {
- name: 'Address',
- created () {
- this.onLoad();
- },
- methods: {
- // 获取数据
- onLoad() {
- // 调用api接口,并且提供了两个参数
- apiAddress({
- type: 0,
- sort: 1
- }).then(res => {
- // 获取数据成功后的其他操作
- ………………
- })
- }
- }
- }
其他的api接口,就在pai.js中继续往下面扩展就可以了。友情提示,为每个接口写好注释哦!!!
$ ^" z0 n ~1 H& N; e; _ api接口管理的一个好处就是,我们把api统一集中起来,如果后期需要修改接口,我们就直接在api.js中找到对应的修改就好了,而不用去每一个页面查找我们的接口然后再修改会很麻烦。关键是,万一修改的量比较大,就规格gg了。还有就是如果直接在我们的业务代码修改接口,一不小心还容易动到我们的业务代码造成不必要的麻烦。. X2 t" G( M* }
好了,最后把完成的axios封装代码奉上。0 o0 Q% ~. S P# j' {
' {7 Q- a% U) j( X- /**axios封装
- * 请求拦截、相应拦截、错误统一处理
- */
- import axios from 'axios';import QS from 'qs';
- import { Toast } from 'vant';
- import store from '../store/index'
-
- // 环境的切换
- if (process.env.NODE_ENV == 'development') {
- axios.defaults.baseURL = '/api';
- } else if (process.env.NODE_ENV == 'debug') {
- axios.defaults.baseURL = '';
- } else if (process.env.NODE_ENV == 'production') {
- axios.defaults.baseURL = 'http://api.123dailu.com/';
- }
-
- // 请求超时时间
- axios.defaults.timeout = 10000;
-
- // post请求头
- axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
-
- // 请求**
- axios.interceptors.request.use(
- config => {
- // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
- // 即使本地存在token,也有可能token是过期的,所以在响应**中要对返回状态进行判断
- const token = store.state.token;
- token && (config.headers.Authorization = token);
- return config;
- },
- error => {
- return Promise.error(error);
- })
-
- // 响应**
- axios.interceptors.response.use(
- response => {
- if (response.status === 200) {
- return Promise.resolve(response);
- } else {
- return Promise.reject(response);
- }
- },
- // 服务器状态码不是200的情况
- 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
- localStorage.removeItem('token');
- store.commit('loginSuccess', null);
- // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
- setTimeout(() => {
- router.replace({
- path: '/login',
- query: {
- redirect: router.currentRoute.fullPath
- }
- });
- }, 1000);
- 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);
- }
- }
- );
- /**
- * get方法,对应get请求
- * @param {String} url [请求的url地址]
- * @param {Object} params [请求时携带的参数]
- */
- 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)
- })
- });
- }
- /**
|