Configuration of axios based on Vue

Keywords: axios Vue less JSON

1, background

  • ajax requests are indispensable in project development
  • Some ajax requests do not require loading or request time is less than how much is not shown loading
  • Assimilation of requests in projects (error handling, return data formatting, loading, token processing)
  • Configuration is based on a personal vue project. The vux-related components are loaded and some dependent import s are made (which can be configured on demand).
import Vue from 'vue'
import axios from 'axios'
//Some environment configuration parameters of the project, read host
import config from '@/config'
//vuex state management, which mainly controls global loading
import store from '@/store'
//Page operation of vue-router for corresponding status code (router instance)
import router from '@/router'
//console corresponding package
import { log } from '@/utils'

2. Solutions

We define several parameters for axios encapsulation.

// Loading Minimum Time
const MINI_TIME = 300
// Time-out (time-out)
let TIME_OUT_MAX = 5000
// Environment value
let _env = process.env.NODE_ENV
// Request interface host
let _apiHost = config.api
// Request group (determine the current number of requests)
let _requests = []

In general, the root host and Content-Type of a project are unified, and axios are configured uniformly here (if the back end needs form data format form, namely content-type='application/x-www-form-urlencoded;charset=utf-8', the request data needs to be serialized, and the quicker way is to introduce QS library qs.stringify for processing and transmission).

axios.defaults.headers.common['Content-Type'] = 'application/json'
axios.defaults.baseURL = _apiHost

In general, there will be more than one request in the project at the same time (not yet returned). To determine whether there is an ongoing ajax, it is necessary to maintain the _requests array.

/**
 * Add a request to display loading
 * @param {Request configuration} config 
 */
function pushRequest(config) {
  log(`${config.url}--begin`)
  _requests.push(config)
  Vue.$vux.loading.show({
    text: 'Loading'
  })
  store.dispatch('loading')
}

/**
 * Remove requests and close loading without requests
 * @param {Request configuration} config 
 */
function popRequest(config) {
  log(`${config.url}--end`)
  let _index = _requests.findIndex(r => {
    return r === config
  })
  if (_index > -1) {
    _requests.splice(_index, 1)
  }
  if (!_requests.length) {
    Vue.$vux.loading.hide(0)
    store.dispatch('loading', false)
  }
}

Next, axios is processed based on the above preparation

/**
 * Request address, request data, silence, request method
 */
export default (url, data = {}, isSilence = false, method = 'POST') => {
  let _opts = { method, url }
  //token
  let _data = Object.assign({}, data, { token: store.getters.token })
  const _query = {}
  for (let _key in _data) {
    if (_data.hasOwnProperty(_key) && _data[_key] !== '') {
      _query[_key] = _data[_key]
    }
  }
  //axios instance request timer ID
  let _timer = null
  //Determine the type of request
  if (method.toLocaleUpperCase() === 'POST') {
    _opts.data = _query
  } else {
    _opts.params = _query
  }
  //Return a promise
  return new Promise((resolve, reject) => {
    //Instantiate axios
    const _instance = axios.create({
      timeout: TIME_OUT_MAX
    })
    //Define the unique identity of the request
    let _random = { stamp: Date.now(), url: `${_apiHost   url}` }
    //Determine silence (silence does not add to the request identification queue, not the timer that declares the request instance)
    if (!isSilence) {
      _timer = setTimeout(() => {
        pushRequest(_random)
      }, MINI_TIME)
    }
    //axios instance sends the current request
    //Request completion: 1. Cancel the timer of the current request; 2. Remove the current identity from the current request identification queue;
    3,Successful returns unified processed data, and failure judges the status code.
    _instance(_opts)
      .then(res => {
        let responseData = res.data
        clearTimeout(_timer)
        popRequest(_random)
        resolve(res.data)
      })
      .catch(res => {
        let _response = res.response
        let _message = null
        clearTimeout(_timer)
        popRequest(_random)
        switch (_response.status) {
          case 404:
            _message = '404,Wrong request'
            break
          case 401:
            router.push({ path: '/login', query: { redirect: router.currentRoute.fullPath } })
            _message = 'Unauthorized'
            break
          case 403:
            _message = 'No access'
            break
          case 408:
            _message = 'request timeout'
            break
          case 500:
            _message = 'Server internal error'
            break
          case 501:
            _message = 'Function not implemented'
            break
          case 503:
            _message = 'Service unavailability'
            break
          case 504:
            _message = 'Bad Gateway'
            break
          default:
            _message = 'unknown error'
        }
        if (!isSilence) {
          Vue.$vux.toast.show({
            text: _response.data && _response.data.error ? _response.data.error : _message,
            type: 'warn',
            width: '10em'
          })
        }
        reject(res)
      })
  })
}

Source file path

# Get a positive, energetic Image

Posted by hoppyite on Wed, 02 Oct 2019 06:27:46 -0700