vue axios二次封装

414 阅读2分钟

一、原因

1、通常来说,项目可能存在多个域名环境(比如测试,生产等), 不同环境访问接口的域名是不同的,可直接修改全局域名。

2、可全局配置头文件,响应错误等信息,不需要单个配置,防止代码累赘,也方便代码维护。

二、axios二次封装

目录utils/http.js

    import axios from 'axios'
    import qs from 'qs'
    import { Message, Loading} from 'element-ui';


    //记录请求次数,防止出现多个请求出现多个loading效果
    let requestCount = 0;
    let loading;
    function startLoading () {
      if (requestCount === 0) {
        loading = Loading.service({
          lock: true,
          text: '加载中……',
          background: 'rgba(0, 0, 0, 0.5)',
        });
      } else { 
        requestCount ++
      }
    }
    function endLoading () {
      if (requestCount <= 0) return;
      requestCount--;
      if (requestCount === 0) {
        // 延迟500ms,防止网速特快加载中画面一闪而过
        setTimeout(function () {
          if (loading) loading.close();
        }, 500);
      }
    }

    // 创建axios实例
    const request = axios.create({
      baseURL: 'url'// 基础请求地址
      // timeout: 15000                  // 请求超时时间
    })
    //响应错误码封装
    function errorMsg (status, msg) {
      status = parseInt(status)
      let result = ''
      switch (status) {
        case 400:
          result = msg ? msg : '请求错误'
          break
        case 404:
          result = msg ? msg : `请求地址出错: ${error.response.config.url}`
          break
        case 500:
          result = msg ? msg : '服务器内部错误'
          break
        case 503:
          result = msg ? msg : '服务不可用'
          break

        default:
          result = msg
      }
      return result
    }

    // request拦截器
    request.interceptors.request.use(config => {

      // 打开loading
      startLoading()
      //配置所需请求投
      config.headers['Authorization'] = "token"
      config.headers['Access-Control-Allow-Origin'] = '*'
      if (config.method === 'post') {
        config.headers["content-type"] = "application/x-www-form-urlencoded"; // post 请求
        config.params = qs.stringify({ ...config.params }) // 序列化,比如表单数据
      } else {
        config.headers["content-type"] = "application/json"; // 默认类型(get)
        config.params = { ...config.params }

      }
      return config
    }, error => {
       // 关闭loading
       endLoading();
       return  Promise.reject(error)
    })

    // response拦截器(响应需求可以和后端沟通配合修改)
    request.interceptors.response.use(
      response => {
        // 关闭loading
        endLoading();
        const res = response.data
        if (res.code === 200) {//成功
          return res
        } else if (res.code === 999) {//token过期
          // 所有请求结束
          if (requestCount === 0) {
            setTimeout(() => {
              //清空token返回登录页
              //........
              // 为了重新实例化vue-router对象 避免bug
              location.reload();
              return
            }, 500)
          }
        } 
      },
      error => {
        // 关闭loading
         endLoading();
        //响应失败,提示失败内容
        if (error && error.response) {
          Message({
            message: errorMsg(error.response.status, error.response.message),
            type: 'error',
            duration: 3 * 1000
          })
        }
        return Promise.reject(error)
      }
    )
    export default request

三、使用

1、目录utils/api.js 存放所有api文件

import { default as request } from '@/utils/http'

const addMsg = (data)=>{
    return  request.post('/message/addMsg', data)
}
//分页获取信息
const getMsgPageList = (data)=>{
    return  request.get('/message/getMsgPageList',{ params: data} )
}
//获取所有信息
const getMsgAllList = ()=>{
    return  request.get('/message/getMsgAllList')
} 
export {
 addMsg,
 getMsgPageList,
 getMsgAllList
}

2、vue文件中使用:

 
  import {addMsg,getMsgAllList} from  '@/utils/api'
  export default {
      methods:{
         handleAddMsg(){
            let params ={
               name:'123',
               massage:'这是一条信息'
            }
            addMsg(params).then(res=>{
               console.log("成功",res)
            }).catch((error) => {
               console.log("失败",error)
            });
         },
         handleGetMsgAllList(){
            getMsgAllList().then(res=>{
               console.log("成功",res)
            }).catch((error) => {
               console.log("失败",error)
            });
         }

      }
  }

3.全局引入请求

  //main.js
  import { default as request } from '@/utils/http'
  Vue.prototype.request = request
  
  //vue页面使用
  this.request.get('/message/getMsgPageList',{ params: data} ).then(res=>{})
  this.request.post('/message/addMsg', data).then(res=>{})