axios 封装

最近一直在写Vue项目,和后台交互用的是官方推荐的axios。

Axios 是一个基于 promise 的 HTTP 库

官方教程里面有详细的使用方法,在此就不做详细描述了~

我们如果在每个需要使用的页面都引入axios 然后写 get、post方法,代码就会变得非常的冗余,会有很多重复的代码,并且需要修改某些通用属性的时候,可能就要涉及到所有的文件。

哪些信息是可以作为公用的

一个完整项目中,所有接口中通用的内容一般包括:

  • 服务器地址
  • 请求成功统一状态码
  • 请求失败不同状态对应的状态码
  • 请求头
开始封装

在文件目录src 下面新建一个api/api.js 文件夹和js文件,然后内部引用所需文件(此处错误信息通过自己封装的一个toast插件得以实现):

import axios from 'axios'
import router from '../router/index.js'

const serverUrl = 'http://172.16.134.81:3344' // 本地测试地址

接下来我们开始封装get请求

// 封装axios get
export function axiosGet(url, params) {
  return axios({
    url: `${serverUrl}${url}`,
    method: 'get',
    params
  })
    .then(res => {
      if (res.data.code === 0) {
        return Promise.resolve(res.data)
      }
      return Promise.reject(res)
    })
    .catch(err => {
     return Promise.reject(err)
    })
}

这里说明一下:

  • 这里的demo 是假设和后台约束了所有的返回体里面 都有code(状态码)、 body(数据内容)、 msg(信息描述);
  • code为0 则请求成功,将数据体 Promise.resolve(),这样就可以在.then()中获取;
  • code不为0的状态都为错误状态 放入 Promise.reject(),然后再 catch()中获取错误信息;
  • catch()中的错误处理,我们会另做特殊处理

然后我们再封装post请求:

// 封装axios post
export function axiosPost(url, data) {
  return axios({
    url: `${serverUrl}${url}`,
    method: 'POST',
    data: data,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  })
    .then(res => {
      if (res.data.code === 0) {
        return Promise.resolve(res.data)
      }
      return Promise.reject(res.data)
    })
    .catch(err => {
     return Promise.reject(err)
    })
}

然后封装一个用axios上传文件的请求:

// 文件上传
function axiosUpload(url, data, callback) {
  const params = data
  return axios
    .post(`${serverUrl}${url}`, params, {
    // 上传进度处理事件
      onUploadProgress(progressEvent) {
        if (progressEvent.lengthComputable) {
          callback(progressEvent)
        }
      }
    })
    .then((res) => {
      if (res.data.code === 0) {
        return Promise.resolve(res.data)
      }
      return Promise.reject(res.data)
    })
    .catch(err => {
      return Promise.reject(err)
    })
}

我们注册一个全局的mixin混入,内容是我们统一处理的一些错误提示,在main.js中:

const networkErr = ['404', '405', '500', '504', '205', '400', 'Network Error']
Vue.mixin({
  methods: {
    errorFun(err) {
      const status = networkErr.some((item) => {
        const errs = err.toString()
        return errs.includes(item)
      })
      if (status) {
        this.$toast('网络错误,请检查网络设置')
        return false
      }
      const response = err.response
      // 登陆过期处理
      if (response && response.data && response.data.code === 100009) {
        this.$toast('登录已过期,请重新登录')
        sessionStorage.clear()
        this.$router.push('/login')
        return false
      }
      this.$toast(err.data.msg)
    }
  }
})

这里面我只列举了一个特殊的处理方法(登陆过期):
和后台约定 当接口返回的状态码为 100009时,则登录超时,此时需要在页面弹出一个message提示,并且清空sessionStorage(如果项目中没有使用则忽略)并且将页面跳转到登录页面
如果还有其他公用的错误提示(例如 500 等)都可以在统一的错误函数中写好,这样就不用再每个页面都重复的写上这些错误处理。然后将这些公用错误之外的其他错误信息返回页面的catch()方法中单独处理~

此时,主要三种请求方法已经封装完成,那么我们怎么使用这三个封装的方法去请求接口呢?

如何使用

在 api.js 后面继续写入具体的接口调用:

// 登录
export function postLogin(data = {}) {
  const url = '/access/login'
  return axiosPost(url, data)
}
// 登出
export function getLogout(data = {}) {
  const url = '/access/logout'
  return axiosGet(url, data)
}
// 资质认证--文件上传
export function postUploadFile(data = {}, callback) {
  const url = '/upload/add'
  return axiosUpload(url, data, callback)
}

这个时候,我们的api.js也算是大功告成了。在Vue文件中我们应该如何调用:

import { postLogin, getLogout, postUploadFile } from '@/api/api.js';
export default {
  methods: {
    /**
     * 登录
     */
    login() {
      const data = {
        name: 'xxxxx',
        password: 'xxxxxxx'
      };
      postLogin(data)
        .then(res => {
          Message({
            message: '登录成功',
            type: 'success'
          });
        })
        .catch(err => {
          this.errorFun(err)
        });
    },
    /**
     * 登出
     */
    logout() {
      getLogout()
        .then(res => {
          // 退出操作
        })
        .catch(err => {
          this.errorFun(err)
        });
    },
    /**
     * 上传文件
     */
    fileChange(e) {
      const params = new FormData();
      const file = e.target.files[0];
      const reader = new FileReader();
      reader.readAsDataURL(file);
      params.set('file', file);
      if (file.size <= 1000000) {
        postUploadFile(params, pro => {
          // pro 为上传进度相关的数据,再此将进度映射到页面中
        })
          .then(res => {
            reader.onload = (() => {
              this.imgUrl = reader.result; // 图片预览 base64码
            })();
          })
          .catch(err => {
            this.errorFun(err)
          });
      }
    }
  }
};

至此,一个完整的axios请求封装与调用已经完成~

本文章的很多写法和理念还不够完善,本人也只是个前端海洋中的一条淡水鱼,在此希望得到广大同行们的指教,共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值