As usual, post the Axios gitHub address first
No matter how you get the data, for a project, the code has to be maintainable and secondly it has to be beautifully written, so a layer of encapsulation is necessary, right
Vujs2.0 no longer maintains Vue-resource, vujs2.0 already uses Axios, which is the main reason why I switched to Axios, without further further:
Basic packaging requirements:
- Unified URL Configuration
- Unified API request
- Request interceptor, such as: with token, set the request header
- Response interceptors, such as uniform error handling, page redirection, etc
- Combine as needed
Vuex
Do global loading animation, or error handling - will
axios
Encapsulated intoVue
The plug-in USES
File structure
Use vue-cli for related encapsulation, in the SRC folder:
The SRC folder | | – HTTP encapsulation axios module — config. The default configuration of js axios — API. Js secondary packaging axios, Interceptors such as —- interface-js request the interface file —- index.js to encapsulate AXIos as a plug-in
config.js
See gitHub for the default configuration. The following is an example:
export default {
method: 'post'.// Base URL prefix
baseURL: 'https://easy-mock.com/mock/5ad75e9f41d4d65f0e935be4/example'.// Request header
headers: {
'Content-Type':'application/json; charset=UTF-8'
},
/ / parameters
data: {},
// Set the timeout period
timeout: 10000.// Carry the certificate
withCredentials: false.// Return the data type
responseType: 'json'
}
Copy the code
PS: Here is a recommended Mock tool, Easy Mock, from which the above request came. I’ll write a little bit about how to use this tool in the future.
api.js
import axios from 'axios' // Install it first
import config from './config.js' // Pour the default configuration
import qs from 'qs' // Serialize the request data, depending on the server's requirements
export default function $axios (options) {
return new Promise((resolve, reject) = > {
const instance = axios.create({
baseURL: config.baseURL,
headers: {},
transformResponse: [function (data) {}]})// Request interceptor
instance.interceptors.request.use(
config= > {
// Tip: 1
// When the request starts, you can start loading animation in full screen with vuex
// Tip: 2
// Take the token, can combine with vuex or localStorage
// if (store.getters.token) {
// config.headers[' x-token '] = getToken() // Let each request carry a Token --[' x-token '] is a custom key. Please modify it according to the actual situation
// } else {
// // Redirects to the login page
// }
// Tip: 3
// Serialize the passed parameters according to the request method, whether serialized according to the backend requirements
if (config.method.toLocaleLowerCase() === 'post'
|| config.method.toLocaleLowerCase() === 'put'
|| config.method.toLocaleLowerCase() === 'delete') {
config.data = qs.stringify(config.data)
}
return config
},
error => {
// Do something when an error is requested (interface error, timeout, etc.)
// Tip: 4
/ / close the loadding
console.log('request:', error)
// 1. Judge the request timeout
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout')! = =- 1) {
console.log('The request has now timed out based on the timeout/ true request you set. You can add a solution for the timeout here.')
// return service.request(originalRequest); // For example, repeat the request again
}
// 2. Redirect to the error page
const errorInfo = error.response
console.log(errorInfo)
if (errorInfo) {
// Error = errorinfo.data // Catch the page to get a detailed error message, look at the bottom promise.reject
const errorStatus = errorInfo.status; // 404 403 500... Etc.
router.push({
path: `/error/${errorStatus}`})}return Promise.reject(error) // Catch the error message you want to return on the side of the call})// Response interceptor
instance.interceptors.response.use(
response= > {
let data;
/ / ie 9 when the response data is undefined, so you need to use the response. The request. The responseText (string) after Stringify
if(response.data == undefined){
data = response.request.responseText
} else{
data = response.data
}
// Depending on the code value returned, do different processing (and back-end conventions)
switch (data.code) {
case ' ':
break;
default:}// If the code is not correct and you are logged in, an error is thrown
// const err = new Error(data.description)
// err.data = data
// err.response = response
// throw err
return data
},
err => {
if (err && err.response) {
switch (err.response.status) {
case 400:
err.message = 'Request error'
break
case 401:
err.message = 'Unauthorized, please login'
break
case 403:
err.message = 'Access denied'
break
case 404:
err.message = Error requesting address:${err.response.config.url}`
break
case 408:
err.message = 'Request timeout'
break
case 500:
err.message = 'Server internal error'
break
case 501:
err.message = 'Service not implemented'
break
case 502:
err.message = 'Gateway error'
break
case 503:
err.message = 'Service unavailable'
break
case 504:
err.message = 'Gateway timeout'
break
case 505:
err.message = 'HTTP version not supported '
break
default:}}console.error(err)
// Here I use the Element UI prompt component
// Message.error(`ERROR: ${err}`);
return Promise.reject(err) // Return the error message returned by the interface})// Request processing
instance(options)
.then((res) = > {
resolve(res)
return false
})
.catch((error) = > {
reject(error)
})
})
}
Copy the code
interface.js
import axios from './api' / / into the API
/* Unify all interfaces for Easy maintenance * if the project is large you can separate the URL into a file and divide the interface into different modules * the data here is still from Easy Mock */
// Pour separately
export const query = params= > {
return axios({
url: '/query'.method: 'get',
params
})
}
export const mock = params= > {
return axios({
url: '/mock'.method: 'get',
params
})
}
export const upload = data= > {
return axios({
url: '/upload'.method: 'post',
data
})
}
// The default is all
// Root is needed
export default {
query,
mock,
upload
}
Copy the code
index.js
Packaged as a Vue plug-in to enable (B) to use (B) (lattice)
// Pour all ports
import apiList from './interface'
const install = Vue= > {
if (install.installed)
return;
install.installed = true;
Object.defineProperties(Vue.prototype, {
// This is mounted on the $API object of the Vue prototype
$api: {
get() {
return apiList
}
}
})
}
export default install
Copy the code
use
At this point, everything is ready. In mian. Js, do the following:
// Pour index.js into the HTTP folder
import api from './http/index'
Vue.use(api)
$API is called directly on the Vue prototype
Copy the code
conclusion
- The above secondary packaging is more comprehensive, basically completing our previous requirements
- In the error processing also needs to be with the back-end agreement good return value, do specific conventions
- Encapsulation callbacks are a bit heavy and need to be added when used
then()
To process the result,async & await
Well, good things should be hidden, I’m not going to share them…
PS: IE9 does not support Promises. You need to install a Polyfill
import 'babel-polyfill'
Copy the code