Vue项目之Axios封装

前言:

axios封装,通过配置请求地址、请求拦截器、响应拦截器、请求方法封装、api接口模块化管理,提高代码的可读性,方便维护代码。

一、结构目录

http.js用于封装axios的配置,包括请求地址、请求拦截器、响应拦截器等。
request.js用于请求方法的封装,包括get、post、文件下载等。
index.js用于api接口统一管理的出口文件。
modules文件夹下面存放各个模块的接口,包括用户、文章、公共数据等。

axios封装目录结构

二、http.js

用于封装axios的配置,包括请求地址、请求拦截器、响应拦截器等。

// 1、引入
import axios from 'axios'
import router from '../router';
import store from '../store'
import { getToken } from '../utils/user'
import { Notification } from 'element-ui';

// 2、配置请求地址公共部分
// 一般项目中存在开发环境、测试环境、生产环境,以及后端人员开发环境的地址,因此需要动态配置请求地址。

if (process.env.NODE_ENV === 'development') {
  axios.defaults.baseURL = 'http://localhost'
} else if (process.env.NODE_ENV === 'debug') {
  axios.defaults.baseURL = ''
} else if (process.env.NODE_ENV === 'production') {
  axios.defaults.baseURL = ''
}

// 3、请求超时时间
// 当请求后端接口超时后,检测到并且提示用户进行相关操作。

axios.defaults.timeout = 5000;

// 4、post请求头
// POST请求头常用类型包含:根据自己的项目自行设置。
// application/x-www-form-urlencoded
// application/json
// text/xml
// multipart/form-data

axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';

// 5、请求拦截器
// 请求拦截,就是我们在发送请求之前,先做一些事情,做完之后再调取后端接口。例如用户身份验证,我们需要将用户的token值放在请求头中,后端拿到token后进行校验等操作。

axios.interceptors.request.use(
  config => {
    // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
    // 此处将token存放在Vuex中,进行查询和保存。
    if (store.getters.token) {
      config.headers['token'] = getToken()
    }
    return config
  },
  error => {
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// 6、响应拦截器
// 请求完后端接口后返回响应数据,我们需要对这个响应进行校验和异常处理,方便及时抛出错误。

axios.interceptors.response.use(
  response => {
    if (response.status === 200) {
      return Promise.resolve(response);
    } else {
      return Promise.reject(response);
    }
  },
  // 服务器状态码不是200的情况
  error => {
    debugger
    // Network Error:网络连接失败。
    // 服务器连接失败,跳转至服务器连接失败显示界面。
    // 在服务器连接成功后返回当前页面
    if (error.message === 'Network Error') {
      Notification({
        title: '提示',
        showClose: true,
        message: '服务器连接失败,请稍后再试!',
        type: 'error'
      });
      router.replace({
        path: '/network_error',
        query: {
          redirect: router.currentRoute.fullPath
        }
      });
    }
    // 以下需根据后端接口统一规定哪些错误方式,进行异常错误处理。
    if (error.response.status) {
      switch (error.response.status) {
        //401:未登录,请求要求用户的身份认证
        //未登录则跳转登录页面,并携带当前页面的路径
        //在登录成功后返回当前页面,这一步需要在登录页操作
        case 401:
          Notification({
            title: "提示",
            showClose: true,
            message: '请登录!',
            type: 'error'
          });
          router.replace({
            path: '/login',
            query: {
              redirect: router.currentRoute.fullPath
            }
          });
          break;

        // 403 token过期,服务器理解请求客户端的请求,但是拒绝执行此请求
        // 登录过期对用户进行提示
        // 清除本地token和清空vuex中token对象
        // 跳转登录页面
        case 403:
          Notification({
            title: "提示",
            showClose: true,
            message: '登录过期,请重新登录',
            type: 'error'
          });
          //清除token

          //跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
          setTimeout(() => {
            router.replace({
              path: '/login',
              query: {
                redirect: router.currentRoute.fullPath
              }
            });
          }, 1000);
          break;

        //404请求不存在,服务器无法根据客户端的请求找到资源
        case 404:
          Notification({
            title: "提示",
            showClose: true,
            message: '网络请求不存在',
            type: 'error'
          });
          break;
        //其他错误,直接抛出错误提示
        default:
          Notification({
            title: "提示",
            showClose: true,
            message: error.response.data.message,
            type: 'error'
          });
      }
    }
    return Promise.reject(error.response);
  }
);
export default axios

三、request.js

此处将GET、POST等常用方法进行封装,同时为了以后方便封装一些其他请求,例如下载文件、webSocket等方法。

import axios from "./http.js"
/**
 * 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)
        })
    });
}

/** 
* post方法,对应post请求 
* @param {String} url [请求的url地址] 
* @param {Object} params [请求时携带的参数] 
*/
export function post(url, params) {
    return new Promise((resolve, reject) => {
        axios.post(url, params)
            .then(res => {
                resolve(res.data);
            }).catch(err => {
                reject(err.data);
            })
    });
}

四、index.js

index.js是一个api接口的出口,这样就可以把api接口根据功能划分为多个模块,利于多人协作开发。

import article from './modules/user';
export default {
    article,
}

五、article.js

article.js是某个功能模块的api接口。

import { get, post } from '../request'
const article = {
   	getList:params=>get('/getArticleList',params)
}
export default article;

六、实例调用

为了方便在组件中调用接口,我们将接口挂载到vue的原型中。

main.js文件:
import api from './api' // 导入api接口
Vue.prototype.$api = api; // 将api挂载到vue的原型上

组件:
<template>
  <div id="app">
    <button @click="handleButton">按钮</button>
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    handleButton() {
      this.$api.article
        .getArticleList({pageIndex:1,pageSize:10})
        .then((result) => {
          console.log(result);
        })
        .catch((err) => {
          console.log(err);
        });
    },
  },
};
</script>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风紧不扯呼_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值