Send a person rose, hand has lingering fragrance, what are you, what is your world 💡
preface
This article takes a look at some of the encapsulation and application of AXIOS in the project. Interested developers are welcome to read this article.
Install dependencies
- Axios installation
# yarn | NPM installation
yarn add axios | npm install axios
Copy the code
- Axios use
import axios from "axios";
axios.post("url",{}).then((res) = > {
// The interface called successfully
}).catch((error) = > {
// Interface call failure destroyed
});
/* Support all HTTP requests, request cancellation, concurrent requests, etc. For more details and how to use the official documentation: [AXIos documentation](http://www.axios-js.com/zh-cn/docs/) */
Copy the code
Configuration axios
Let’s get back to the focus of this article, how to properly configure it to improve development efficiency and maintainability.
-
To create the configuration file, we’re just wrapping axios a little bit, so create the config folder under SRC and the axios.js file under config
-
The wrapped AXIOS configuration code is as follows. Place the following code in the axios.js file.
/** * Encapsulate AXIos slightly * 1. Set request timeout * 2. Add a request interceptor and add token * to the header of each request. 3. Add a response interceptor and return */ based on the server return status
"use strict";
import axiosObj from "axios";
// To import the VUEX, you need to obtain the token stored in it. If you do not need the token, you do not need to import the vuex
import store from ".. /store";
const defaultConfig = {
// baseURL is omitted here. Considering that the project may be developed by many people and the domain name may be different, the domain name is configured in base.js separately by pulling out the API
// Request timeout
timeout: 60 * 1000.// Whether credentials are required for cross-domain requests
// withCredentials: true, // Check cross-site Access-Control
heards: {
get: {
// Set the default request header. When a special request header is needed, pass it as a parameter to override the default parameter
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"
},
post: {
// Set the default request header. When a special request header is needed, pass it as a parameter to override the default parameter (config).
/ / such as:
// services.post(`${base.lkBaseURL}/uploads/singleFileUpload`, file, {
// headers: { "Content-Type": "multipart/form-data" }
/ /});
"Content-Type": "application/json; charset=utf-8"}}// The data is processed before the request is sent to the server and axios serializes the data by default
// transformRequest:[function(data){
//
// }],
// Modify the response data before passing it to then/catch
// transformResponse:[function(data){
//
// }]
};
/** * Request failure after the unified processing, of course, there are more status code judgment, according to your business needs to expand *@param Status Indicates the status code * of the failed request@param MSG Error message */
const errorHandle = (status: number, msg: string) = > {
// Determine the status code
switch (status) {
// 401: Login page is displayed
case 401:
// Jump to the login page
break;
// 403 Token expired
case 403:
// If you do not need to refresh the tokens automatically, you can remove the tokens from the local storage to switch to the login page
break;
// 404 request does not exist
case 404:
// The resource does not exist
break;
default:
console.log(msg); }};// Create an instance
const _axios = axiosObj.create(defaultConfig);
// Request interceptor
_axios.interceptors.request.use(
function(config) {
// Get the token from vuex
const token = store.state.token;
// If the token exists, add it to the request header
token && (config.headers.token = token);
return config;
},
function(error) {
// Do something with request error
error.data = {};
error.data.msg = "Server exception";
return Promise.reject(error); });// Response interceptor
_axios.interceptors.response.use(
function(response) {
// Clear the tokens in the local storage. If you need to refresh the tokens, exchange the old tokens with the server and add the new tokens to the VUEX
if(response.data? .code ===401) {
localStorage.removeItem("token");
// Page refresh
parent.location.reload();
}
if (response.status === 200) {
// Process data in the interface
if(response.data? .data) {try {
const dataObj = JSON.parse(response.data.data);
if (typeof dataObj == "object" && dataObj) {
// Convert a JSON string to a JSON objectresponse.data.data = dataObj; }}catch (e) {
// If it is not a JSON string, it is not processed
returnresponse.data; }}return response.data;
}
response.data.code = -1;
response.data.msg = "Server error";
return response;
},
function(error) {
if (error) {
// The request has been sent, but not in 2xx
errorHandle(error.status, error.data.msg);
return Promise.reject(error);
} else {
/ / broken network
return Promise.reject(error); }});export default _axios;
Copy the code
Now that the core configuration of AXIos is complete, let’s take a look at what the configuration does.
- Setting timeout
- Centralized configuration of request headers
- If the response fails, the status code is processed uniformly
- Add tokens to request interception
- Token expiration and returned data are processed accordingly in response interception
- Description The interface domain name is removed
- And then finally we export that, which we’ll use when we pull out of the API
Separate API and domain name interface
Why do I do API extraction? If we write this.$axios.get() in the business code for all of our requests, we will have to go to the business code one by one to find and modify the request. There is no maintenance at all. Next we will take you to implement API separation 😃
Implementation approach
We will improve the maintainability of the project interface by following several steps:
- Create an interface module file, write the interface address, parameters, and request mode in the file, and export the file for reference in the API unified export file.
- Create the interface domain name file. There may be multiple interface domain names in the team. We will write them here and export them for reference in the interface module file.
- Create a unified API exit file and divide the API interface into multiple modules based on function (Step 1), which is convenient for multi-person development. Appoint the module leader in the team, introduce all modules here, expose references, and then mount the Vue prototype both through this.$API. Module name. Method name for reference.
The implementation code
- Create the API folder under SRC
- Create an interface domain name file
index.js
/* * interface domain name management * * */
const base = {
lk:"https://www.kaisir.cn/user".other:"https://kf.kaisir.cn/api"
};
export default base;
Copy the code
- in
api
Create an interface module file in the folder named as follows:Module name + API
.
/* * webmaster * */
import services from '.. /plugins/axios'
import base from './base'; // Import the interface domain name list
const websiteManageAPI = {
/ / login
login(params){
return services._axios.post(`${base.lk}/login`,params);
},
// Test the POST interface
postJSON(params){
return services._axios.post(`${base.lk}/getter/postJSON`,params);
},
// Test the GET interface
getJSON(pageNo,pageSize){
return services._axios.get(`${base.lk}/getter/getJSON`, {params: {pageNo:pageNo,pageSize:pageSize}}); }};export default websiteManageAPI;
Copy the code
- Create an API unified export file
/** * API unified exit ** /
// Site management interface
import websiteManageAPI from './websiteManageAPI';
// Other module interfaces
// Export interface
export default {
websiteManageAPI,
// ...
}
Copy the code
After completing the above steps, the contents of the API folder should look like the following.
Next, we can choose to mount what is exposed by the API unified exit file to the prototype. Or choose load on demand and import whichever module is used in the business code.
Here’s how to mount it to the prototype by adding the following code to the entry file mian.js.
// Mount to the prototype (main.js)
Vue.prototype.$api = api;
Copy the code
Adapter Vue3
When used in Vue3, the idea of body encapsulation is the same. If the project uses TypeScript, there will be a type declaration in the AXIos configuration file. If you need to mount the API to the prototype, you will need to declare the API type in the declaration file. In the main. Js mount writing need to app. Config. GlobalProperties. = $API API; .
On October 20, 2020, I reconstructed the previous project with Vue3. The axios configuration code address for Vue3 is as follows:
API folder: SRC/API
Axios configuration file: config/axios.ts
Vue type declaration file: SRC /shims-vue.d.ts
Developers interested in refactoring the Vue2 project with Vue3 can take a step further: Refactoring the Vue2 project with Vue3
The practical application
For example, all back-end interfaces need to be logged in to and accessed based on the token returned after successful login. Back-end interfaces use ShirO + JWT to implement interface authentication and token provisioning
- When the page loads, the token is obtained from the local store
// app. vue,created lifecycle
const token = localStorage.getItem("token");
Copy the code
- Check whether the token exists and obtain it if it does not
//
if(lodash.isEmpty(token)){
// Login page: This step is only used for demonstration purposes. The user name and password are fixed data
const userInfo = {
"username":"Test"."password":"0x89oikklsa"
};
// Call the login API
this.$api.websiteManageAPI.login(userInfo).then((res) = >{
// Store the token and update it to the vuEX
localStorage.setItem("token",res.token);
this.$store.state.token = res.token;
});
}else{
// Update the tokens in vuEX
this.$store.state.token = token;
}
Copy the code
- The execution result
- Call other interfaces to test whether the request header token is added successfully
// Test whether other interfaces can be called successfully
this.$api.websiteManageAPI.getJSON(1.3).then((res) = >{
console.log("Interface call successful");
console.log(res)
});
}
Copy the code
- The execution result
Write in the last
- If there are any errors in this article, please correct them in the comments section. If this article helped you, please like it and follow 😊
- This article was first published in the Nuggets. If you need to reprint it, please leave a comment at 💌