vue项目使用axios封装请求或者其他类型请求封装

先看一个开源项目的写法,就非常符合需求了

import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// create an axios instance
const service = axios.create({
  baseURL: process.env.BASE_API, // api 的 base_url
  timeout: 50000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // Do something before request is sent
    if (store.getters.token) {
      // 让每个请求携带token-- ['X-Litemall-Admin-Token']为自定义key 请根据实际情况自行修改
      config.headers['X-Litemall-Admin-Token'] = getToken()
    }
    if (store.getters.language) {
      config.headers['language'] = store.getters.language
    }
    return config
  },
  error => {
    // Do something with request error
    console.log(error) // for debug
    Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  response => {
    const res = response.data

    if (res.errno === 501) {
      MessageBox.alert('系统未登录,请重新登录', '错误', {
        confirmButtonText: '确定',
        type: 'error'
      }).then(() => {
        store.dispatch('FedLogOut').then(() => {
          location.reload()
        })
      })
      return Promise.reject('error')
    } else if (res.errno === 502) {
      MessageBox.alert('系统内部错误,请联系管理员维护', '错误', {
        confirmButtonText: '确定',
        type: 'error'
      })
      return Promise.reject('error')
    } else if (res.errno === 503) {
      MessageBox.alert('请求业务目前未支持', '警告', {
        confirmButtonText: '确定',
        type: 'error'
      })
      return Promise.reject('error')
    } else if (res.errno === 504) {
      MessageBox.alert('更新数据已经失效,请刷新页面重新操作', '警告', {
        confirmButtonText: '确定',
        type: 'error'
      })
      return Promise.reject('error')
    } else if (res.errno === 505) {
      MessageBox.alert('更新失败,请再尝试一次', '警告', {
        confirmButtonText: '确定',
        type: 'error'
      })
      return Promise.reject('error')
    } else if (res.errno === 506) {
      MessageBox.alert('没有操作权限,请联系管理员授权', '错误', {
        confirmButtonText: '确定',
        type: 'error'
      })
      return Promise.reject('error')
    } else if (res.errno !== 0) {
      // 非5xx的错误属于业务错误,留给具体页面处理
      return Promise.reject(response)
    } else {
      return response
    }
  }, error => {
    console.log('err' + error)// for debug
    Message({
      message: '登录连接超时(后台不能连接,请联系系统管理员)',
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  })

export default service

这里主要做的就是封装之前的拦截,拦截没有token,拦截没有权限的,还有一些非常常规的异常处理,主要看一下这些处理,如果是error都会扔到return Promise.reject('error')

两个关键点在这里

vue项目使用axios封装请求或者其他类型请求封装_第1张图片

然后再看api的页面怎吗使用的

import request from '@/utils/request';

const IndexUrl = 'wx/home/index'; //普通get函数不要参数的
export function getHome() {
  return request({
    url: IndexUrl,
    method: 'get'
  });
}

const CatalogCurrent = 'wx/catalog/current'; //get函数要传参数的
export function catalogCurrent(query) {
  return request({
    url: CatalogCurrent,
    method: 'get',
    params: query
  });
}

const AuthLoginByAccount = 'wx/auth/account/login'; //post要传参数的
export function authLoginByAccount(data) {
  return request({
    url: AuthLoginByAccount,
    method: 'post',
    data
  });
}

const AuthLogout = 'wx/auth/logout'; //post不传参数的写法
export function authLogout() {
  return request({
    url: AuthLogout,
    method: 'post'
  });
}

看吧,此时你export出去这个接口,在其他页面要用的时候直接 这样

impot { getList } from '@/api';

使用就是这样

import { getHome, goodsCategory, couponReceive } from '@/api/api';
export default {
  mixins: [scrollFixed],

  data() {
    return {
      shopInfos: [],
      isLoading: false
    };
  },

  created() {
    this.initViews();
  },

  methods: {
    getCoupon(id) {
      couponReceive({ couponId: id })
        .then((res) => {
          // 这个res就是后台回来的,记得要看下结构哦 
          // 处理成功回调了
          Toast.success(this.$t('tabbarHome.getSuccess'));
        })
        .catch(e => {
          // 处理某异常逻辑
        });
    },
    changeTabbar(o) {
      // 这种就是传参数了,和上边一样有then和catch
      goodsCategory({ id: o.id }).then(res => {
        let categoryId = res.data.data.currentCategory.id;
        this.$router.push({
          name: 'category',
          query: { itemClass: categoryId }
        });
      });
    },
    initViews() {
      getHome().then(res => {
        this.shopInfos = res.data.data;
      });
    }
  
  },

  components: {
    [Row.name]: Row,
    [Col.name]: Col,
    [Card.name]: Card,
    [Toast.name]: Toast,
    [CouponCell.name]: CouponCell,
    [CouponList.name]: CouponList
   
  }
};

还有一些情况是用的第三方接口,不能用axios(需求你知道的。有什么很诡异,没办法);

比如引入融云的聊天系统,他有自己调取的方法,而且有自己的回调函数,这个时候我们又不能去他回调函数里去写。那就只能用promise封装了,直接看代码,下边的代码也放在api.js文件里,用法和上边一样。也是then也是catch,利用promise我们就知道他啥时候回调了。否则那真是噩梦。

export function getHistoryMessages(data) {
  // 获取单群聊历史消息
  return new Promise((resolve, reject) => {
    // var conversationType = RongIMLib.ConversationType.PRIVATE; //单聊, 其他会话选择相应的会话类型即可
    // var targetId = 'user1'; // 想获取自己和谁的历史消息,targetId 赋值为对方的 Id
    // var timestrap = null; // 默认传 null,若从头开始获取历史消息,请赋值为 0, timestrap = 0;
    // var count = 20; // 每次获取的历史消息条数,范围 0-20 条,可以多次获取
    const { conversationType, targetId, timestrap, count } = Object.assign({},data);
    // 下边这个注释是因为RongIMLib是全局变量又没有显示声明,eslint不知道已经存在
    // eslint-disable-next-line 
    RongIMLib.RongIMClient.getInstance().getHistoryMessages(
      conversationType,
      targetId,
      timestrap,
      count,
      {
        onSuccess: function(list, hasMsg) {
          // list => Message 数组。
          // hasMsg => 是否还有历史消息可以获取。
          // then不处理第二个参数,所以只能传一个参数
          resolve({ list, hasMsg });
        },
        onError: function(error) {
          reject(error);
        }
      }
    );
  });
}

还有一个特殊情况就是上传文件,照片等

const StorageUpload = 'wx/storage/upload'; //上传
export function sorageUpload(data) {
  return request({
    url: StorageUpload,
    method: 'post',
    transformRequest: [
      function(data) {
        // 对 data 进行任意转换处理 上传之前干点事情
        let formData = new FormData();
        formData.append('file', data, data.name);
        return formData;
      }
    ],
    data
  });
}

完结,有不对的地方望指正!

你可能感兴趣的:(Vue相关,vue项目的接口封装)