vue对ajax进行封装从而全局简单调用

20 篇文章 0 订阅

vue对ajax进行封装从而全局简单调用
具体操作具体更改,这里的apiMap是默认自动更新的接口文档,可以自己删掉进行更改
全局挂载

import Vue from 'vue'
import apiMap from './apis.js'
let loadingNum = 0
let loadingTimeout
let loading
let loadingTimes = 0
Vue.prototype.http = async function ({cmd, type, input, success, error, complete, ...arg}) {
  let self = this
  if (!apiMap[cmd]) {
    throw new Error('找不到 api:' + cmd + ', 请确认')
  }
  let isAjaxComplete = false
  addLoading()
  let http = await ajax()
  let result = responseHandler(http)
  reduceLoading()
  return result
  async function ajax () {
    let _http
    await new Promise(resolve => {
      const http = new XMLHttpRequest()
      http.onreadystatechange = function () {
        if (http.readyState === 4) {
          _http = http
          isAjaxComplete = true
          resolve()
        }
      }
      let url = window.config.host + apiMap[cmd].uri + '?src=H5'
      if (!input) {
        input = {}
      }
      input = JSON.parse(JSON.stringify(input))
      if (apiMap[cmd].type === 'GET') {
        var getParam = '&'
        Object.keys(input).forEach(function (key) {
          var item = input[key]
          if (key === 'pIdx') {
            item = item - 1
          }
          if (typeof item === 'object') {
            if (item instanceof Array) {
              // 数组进行逗号组合为字符串
              if (item.length > 0) {
                item = item.join(',');
                getParam += key + '=' + item + '&'
              }
            } else {
              item = encodeURIComponent(item)
              getParam += key + '=' + JSON.stringify(item) + '&'
            }
          } else if (item || item === 0) {
            item = encodeURIComponent(item)
            getParam += key + '=' + item + '&'
          }
        })
        if(!getParam.includes('mchId')){
          getParam += 'mchId=' + window.localStorage.mchId + '&'
        }
        if (getParam === '&') {
          getParam = ''
        }

        url += getParam.replace(/&$/, '')
      } else if (apiMap[cmd].type !== 'DELETE') {
        removeEmpty(input)
      }
      http.open(apiMap[cmd].type || 'POST', url.replace(/\{.+\}/, arg.id), true)
      http.setRequestHeader('sessionId', window.localStorage.sessionId)
      http.setRequestHeader('Content-type', 'application/json')
      http.send(JSON.stringify(input))
    })
    return _http
  }
  function responseHandler (http) {
    if (!http.responseText) {
      return {code: 'failed', msg: '请求无响应'}
    }
    let res = JSON.parse(http.responseText)
    if (http.status === 200) {
      if (res.code === 401) {
        // window.location.href = window.location.href.split('/#/')[0] + '/login.html'
        // uni.postMessage({
        //   data: {
        //     type:'navigateToMiniProgram',
        //   },
        //   success(){
        //     // uni.navigateBack()
        Vue.prototype.$toast.fail('当前登录已过期,请重新登录')
        setTimeout(() => {
          uni.navigateTo({url:'/pages/login/index'})
        }, 1000);
        //   }
        // });
        return
      } else if (res.code !== 200 && (!success || !success.toString().includes('$message'))) {
        // 如果状态码不是 200,并且 success 函数里没有提示相关的错误信息,那么这里提示一下 TODO 会不会有不需要提示的情况 ?
        // Vue.prototype.$message.error(res.msg)
        Vue.prototype.$toast.fail(res.msg)
      }
      if (res.msg === 'OK') {
        res.msg = '操作成功'
      }
      success && success.call(self, res)
    } else {
      error && error.call(self, res)
    }
    complete && complete.call(self, res)
    return res
  }
  
  function addLoading () {
    loadingNum++
    if (loadingTimeout) return
    loadingTimeout = setTimeout(() => {
      // loading了 n 次了, 友情提示一下
      // 第一次 loading 2次, 提示一下
      // 之后每 loading 5次, 提示一下
      if (!isAjaxComplete) {
        loadingTimes++
        let target = document.getElementById("loading-overlay")
        if (target) {
          target.style.display = 'flex'
          loading = target
        }
        if (loadingTimes === 2) {
          // Vue.prototype.$message.warning('您的网络比较差, 操作响应时间会比较长, 请耐心等候')
          loadingTimes = -3
        }
      }
    }, 1000)
  }
}
function reduceLoading () {
  loadingNum--
  if (loadingNum <= 0) {
    clearTimeout(loadingTimeout)
    loadingTimeout = loadingNum = 0
    if (loading) {
      console.log("关闭loading")
      document.getElementById("loading-overlay").style.display = 'none'
      loading = null
    }
  }
}

// 过滤空字符串为 undefined
function removeEmpty (obj) {
  if (obj instanceof Array) {
    obj.forEach(removeEmpty)
  } else {
    Object.keys(obj).forEach(key => {
      if (obj[key] === '') {
        obj[key] = undefined
      }
    })
  }
}

实际用法:

getData(){
      this.http({
      cmd: 'GETIdxReportStats',
      input: {enable:'off'},
      id: '123',
      success (res) {
        console.log(res)
      }
    });
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_小郑有点困了

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

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

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

打赏作者

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

抵扣说明:

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

余额充值