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)
})
})
}
# Get a positive, energetic Image