实现axios的统一封装API,axios结果格式处理,vue组件的loading动画变量在axios请求的前后改变

当需要对axios进行封装以便于ajax请求的统一管理时可使用此方法绑定

  1. 可实现相应数据的统一处理返回
  2. vue 的this.loading在请求前后的改变
  3. 错误的统一处理方式

api定义绑定

// 绑定方法定义
function bindErrHandle (api) {
  return function () {
    let CurArr = [...arguments]
    let options = {
      /**
       * loding数组为字符串表示obj名
       * example:loading为 this.a.b  ,传入loading: ['a.b']
       * this可通过call、apply、option{this:this}3种方式传入
       */
      loading: [],
      loadingFunc: null,
      this: this,
      defaultErrhandle: false
    }

    // API 定义外的后一个参数为options
    if (api.length < CurArr.length &&
      CurArr[api.length] instanceof Object) {
      Object.assign(options, CurArr[api.length])
    }

    if (options.loading.length > 0) {
      options.loadingFunc = (function () {
        let objH = {}
        objH.start = function () {
          for (let item of options.loading) {
            if (typeof item !== 'string') continue
            setCurThisLoading(options.this, item, true)
          }
        }
        objH.end = function () {
          for (let item of options.loading) {
            if (typeof item !== 'string') continue
            setCurThisLoading(options.this, item, false)
          }
        }
        return objH
      })()
    }

    if (options.loadingFunc) options.loadingFunc.start()

    return api.apply(null, arguments).then(res => {
      if (options.loadingFunc) options.loadingFunc.end()

      if (res.data) return Promise.resolve(res.data)
      return Promise.resolve(res)
    }).catch(err => {
      if (options.loadingFunc) options.loadingFunc.end()

      // 通用处理部分
      // console.log('错误中间通用处理!!!', api.name, err, '\n\n')
      return Promise.reject(err)
    })
  }
}

// 设置vue v-loading的值
function setCurThisLoading (obj, str, blo) {
  let strArr = str.split('.')
  let thisObj
  for (let i = 0; i < strArr.length; i++) {
    if (i === strArr.length - 1 && i === 0) {
      obj[strArr[i]] = blo
    } else if (i === strArr.length - 1) {
      thisObj[strArr[i]] = blo
    } else if (thisObj) {
      thisObj = thisObj[strArr[i]]
    } else {
      thisObj = obj[strArr[i]]
    }
  }
}


// 可单独放置在一个api.js文件中
let apiExport = {
    getUserInfo(id) { //api 只需如此定义,
     	console.log('api调用')
        return axios.get('/userinfo/'+id)
    },
    company:{
        getInfo(){
            return axios.get('/v1/info')
        }
        ...
    },
    apiA: (id, b) => axios.get(id, b), // 也可如此定义
}
apiExport = eachBind //遍历绑定后,每一个方法的最后一个参数紧接的参数为options设置
export default apiExport

调用方式

// 外部vue调用 api
import api from './api.js'

let obj = { // 模拟vue模块this
    loading: false
}

api.getUserInfo.call(obj,userid,{loading:['loading']})
.then(res => {
    console.log('外部调用res', res, obj)
}).catch(err => {
    console.log('外部调用err', err, obj)
})

// 
/**
axios resolve时输出的结果顺序
>>>
api调用
start loading true
end loading false
外部调用res, 响应的结果(如果res.data存在此处返回res.data), {loading: true}(vue的this。loading数据被改变)
 */
 
 /**
axios reject时输出的结果顺序
>>>
api调用
start loading true
end loading false
外部调用err, 响应的结果(如果res.data存在此处返回res.data), {loading: true}(vue的this。loading数据被改变)
 */
  

猜你喜欢

转载自blog.csdn.net/guang_sszbs/article/details/89228808