2

85

vue 最佳解决方案

Cabber

2019-10-09 11:21:37

开源项目 https://github.com/xiejunping/andt-components

项目描述

这是一个vue-cli 3.x 构建的vue框架,按需加载 andt-design-vueiview 处理了不兼容的问题。

andt-design-vue 中的spin的用法很有局限性,

不支持相对位置显示 不支持全局方法显示与关闭 可以包裹,但不能在子组件中关闭

接口请求

  • 优化原有的三种方式的请求 json,x-www-form-urlencoded,form-data

  • 分别对应 request.class.js 里的 reqJson,reqData,reqFormData 同时在这次优化请求中增加了cancelRequest取消方法,并深度测试了其取消功能,在单接口或是多接口的同时,都可以使用取消机制

测试取消需配合长延迟接口做实验,代码中增加了delay60s,长等待接口,并测试了axios的超时限制,浏览器超时限制,google chrome的前端超时限制是4分钟。

  • 优化请求全屏遮罩动画,并增加取消按钮功能,在前后端开发的功能中,如出现错误,及接口等待时间过长,用户可手动取消,增加用户的体验度。

request.class.js


import axios from 'axios'
import ReqClient from './interceptor'
import { message } from 'ant-design-vue'
import { RES_CODE } from './config'
import { Spin } from 'iview'

const CancelToken = axios.CancelToken
const source = CancelToken.source()

async function fmtResponse (response) {
  const { status, data } = response
  // HTTP状态码不正确
  if (status === 200) {
    if (data && data.code === RES_CODE) {
      return data.data
    } else if (data && data.msg) {
      message.error(data.msg, 5)
      throw response
    } else {
      message.error('接口返回的格式错误', 5)
      throw response
    }
  } else {
    switch (status) {
      case 403:
        message.error('服务器拒绝请求!', 5)
        break
      case 404:
        message.error('服务器找不到请求!', 5)
        break
      case 408:
        message.error('网络已超时,请重试!', 5)
        break
      case 500:
        message.error('服务器出错了!', 5)
        break
      case 503:
        message.error('服务器宕机了-_-。sorry!', 5)
        break
      case 504:
        message.error('服务器没有反应了!', 5)
        break
      default:
        message.error('网络错误! 请重试', 5)
        break
    }
    throw response
  }
}

export async function reqJson (config) {
  try {
    config = Object.assign(config, {
      headers: {
        put: { 'Content-Type': 'application/json' },
        post: { 'Content-Type': 'application/json' },
        patch: { 'Content-Type': 'application/json' }
      },
      cancelToken: source.token
    })
    const response = await ReqClient.request(config)
    return await fmtResponse(response)
  } catch (e) {
    if (axios.isCancel(e)) {
      message.error(e.message)
      Spin.hide()
    }
    return false
  }
}

export async function reqData (config) {
  try {
    config = Object.assign(config, {
      cancelToken: source.token
    })
    const response = await ReqClient.request(config)
    return await fmtResponse(response)
  } catch (e) {
    if (axios.isCancel(e)) {
      message.error(e.message)
      Spin.hide()
    }
    return false
  }
}

export async function reqFormData (config) {
  try {
    config = Object.assign(config, {
      headers: {
        put: { 'Content-Type': 'multipart/form-data' },
        post: { 'Content-Type': 'multipart/form-data' },
        patch: { 'Content-Type': 'multipart/form-data' }
      },
      cancelToken: source.token
    })
    const response = await ReqClient.request(config)
    return await fmtResponse(response)
  } catch (e) {
    if (axios.isCancel(e)) {
      message.error(e.message)
      Spin.hide()
    }
    return false
  }
}

export function cancelRequest () {
  source.cancel('请求已被取消')
}

interceptor.js

import axios from 'axios'
import Qs from 'qs'
import FormData from 'form-data'
import store from '@/store'
import { Spin } from 'iview'
import { HOST_API } from './config'

function formDate (obj) {
  let form = new FormData()
  for (const key in obj) {
    if ({}.hasOwnProperty.call(obj, key)) {
      // 数组处理
      if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
        obj[key].forEach(ret => {
          form.append(key, ret)
        })
      } else form.append(key, obj[key])
    }
  }
  return form
}

const instance = axios.create({
  baseURL: HOST_API,
  transformRequest: [function (data, headers) {
    const ContentType = headers.post['Content-Type'] || headers.put['Content-Type'] || headers.patch['Content-Type']
    if (ContentType.includes('json')) data = JSON.stringify(data)
    else if (ContentType.includes('form-data')) data = formDate(data)
    else data = Qs.stringify(data)
    return data
  }],
  paramsSerializer: function (params) {
    return Qs.stringify(params)
  },
  timeout: 10000,
  headers: {
    'X-Requested-With': 'XMLHttpRequest'
  },
  onUploadProgress: function (e) {
    Spin.show()
  },
  onDownloadProgress: function (progressEvent) {
    Spin.hide()
  },
  maxContentLength: 200000
})

if (store.state.token) {
  instance.defaults.headers.common['Authorization'] = store.state.token
}

export default instance


发表评论

登陆 后发表评论

评论列表

还没有评论,快来做第一个评论的人吧