vue encapsulates axios and realizes unified management of api interface

  • 2021-10-15 09:44:47
  • OfStack

In the vue project, we usually use axios to interact with the background. axios has many easy-to-use features, which are not introduced here. For relevant details, please refer to axios Chinese website. Before encapsulating axios, we'll create an vue project using the vue scaffolding tool (I'm using cli4 here).

Installation


cnpm install axios --save-dev; //  Installation axios
cnpm install qs --save-dev; //  Installation qs Module to serialize post Type, otherwise the backend cannot receive the data 

Module introduction

Create an service directory under the src directory, which is used to store the related files of interface encapsulation. Then create service. js in the service directory for the introduction of axios and qs modules, and encapsulate axios in this file. The code is as follows (if there is only one interface domain name):


import axios from 'axios' // Introduce axios
import qs from 'qs' // Introduce qs Which is used to serialize post Type, otherwise the backend cannot receive the data 
//  Settings post Request header 
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
axios.defaults.withCredentials = false;// When cross-domain requests are made, user credentials are not carried; Returned  response  It will also be ignored in  cookie

// Create axios Instance, the request timeout time is 300 Seconds 
const instance = axios.create({
 timeout: 300000,
});

// Request and response interceptions can be written according to actual project requirements 
//  Intercept before request initiation 
instance.interceptors.request.use((config) => {
// You can operate on the interface request header here   Such as: config.headers['X-Token'] = token
 console.log(" Request interception ",config);
 return config;
}, (error) => {
 // Do something with request error
 return Promise.reject(error)
})

//  Response interception (interception after request return) 
instance.interceptors.response.use(response => {
 console.log(" Response interception ",response);
 return response;
}, error => {
 console.log('catch', error)
 return Promise.reject(error)
})

// According to the request type axios Encapsulate 
const api={
 get(url,data){
	return instance.get(url,{params:data})
 },
 post(url,data){
	return instance.post(url,qs.stringify(data))	
 }, 
}
export {api}

The above code is the case where there is only one interface domain name (most cases). When there are multiple interface domain names (a few cases), we need to transform the previous encapsulation. The code is as follows:


import axios from 'axios' // Introduce axios
import qs from 'qs' // Introduce qs Which is used to serialize post Type, otherwise the backend cannot receive the data 
//  Settings post Request header 
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
axios.defaults.withCredentials = false;// When cross-domain requests are made, user credentials are not carried; Returned  response  It will also be ignored in  cookie

// Create axios Instance, the request timeout time is 300 Second, because there are multiple domain names in the project, you should also create multiple corresponding domain names axios Instances 
const instanceA = axios.create({
 timeout: 300000,
});
const instanceB = axios.create({
 timeout: 300000,
});

// If the item is single 1 Domain name, you don't need to configure it here. When there are multiple domain names in the project interface, you should axios Instance base path, otherwise it cannot be called differently in the project production environment 
if (process.env.NODE_ENV == 'production') {
 instanceA.defaults.baseURL = 'https://www.production_a.com';
 instanceB.defaults.baseURL = 'https://www.production_b.com';
}

// Request and response interceptions can be written according to actual project requirements 
//  Intercept before request initiation 
instanceA.interceptors.request.use((config) => {
// You can operate on the interface request header here   Such as: config.headers['X-Token'] = token
 console.log(" Request interception ",config);
 return config;
}, (error) => {
 // Do something with request error
 return Promise.reject(error)
})
instanceB.interceptors.request.use((config) => {
 console.log(" Request interception ",config);
 return config;
}, (error) => {
 // Do something with request error
 return Promise.reject(error)
})

//  Response interception (interception after request return) 
instanceA.interceptors.response.use(response => {
 console.log(" Response interception ",response);
 return response;
}, error => {
 console.log('catch', error)
 return Promise.reject(error)
})
instanceB.interceptors.response.use(response => {
 console.log(" Response interception ",response);
 return response;
}, error => {
 console.log('catch', error)
 return Promise.reject(error)
})

// According to the request type axios Encapsulate 
const api={
 get(url,data){
	return instanceA.get(url,{params:data})
 },
 post(url,data){
	return instanceA.post(url,qs.stringify(data))	
 },
 doGet(url,data){
	return instanceB.get(url,{params:data})
 },
 doPost(url,data){
	return instanceB.post(url,qs.stringify(data))	
 } 
}
export {api}

In the above code, the basic path of axios instance is configured according to the production environment. If there are multiple environments in the project (such as test environment, etc.), the CLI4 scaffold environment variable needs to be configured

api Interface System 1 Management

Split api interface according to functional modules, and write the interface under the same module in the same file for unified management, so that the code will be easier to maintain. For example, there are news modules and music modules in our projects. We will create news. js and music. js files in the serviec directory to manage all api interfaces of their respective modules. Here I only take news. js files as an example, and the code is as follows:


import {api} from "./service.js";	
const news={
	getNewsList(){// Get a news list 
		return api.get("api/news/getNewsList")
	},
	editNewsDetail(data){// Revise the news details 
		return api.post("api/news/editNewsDetail",data);
	}
}
export default news;

In order to make it easier to call these encapsulated interfaces in the project, we need to mount these interfaces on the prototype of vue. First, we need to create api. js files in the service directory, introduce api management files of all modules, and then export them in a unified way. The code is as follows:


// Introducing correlation api Management module 
import news from "./news.js";
// Progressive system 1 Export 
export default {
	news
}

Locate the main. js file in the project and mount the interface on the prototype of vue, as follows:


import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'
Vue.prototype.axios=axios
Vue.config.productionTip = false
import api from "./service/api.js";
// Mount the encapsulated interface to the vue Prototype 
Vue.prototype.$api = api;
new Vue({
 router,
 store,
 render: h => h(App)
}).$mount('#app')

Then the template file App. vue, which we automatically generate when the project is created, calls the encapsulated interface with the following code:


<template>
 <div id="app">
 <div id="nav">
	<router-link to="/">Home</router-link> |
	<router-link to="/about">About</router-link>
	<button @click="getN"> Interface encapsulation getN</button>
	<button @click="postN"> Interface encapsulation postN</button>
 </div>
 <router-view/>
 </div>
</template>
<script>

export default {
	methods:{
		getN(){
			this.$api.news.getNewsList().then((res)=>{
				console.log(res);
			})
		},
		postN(){
			let openid="oO5tQ5VMPpuzLqwfXhpmwjqwSANM";
			let productCodes="pro-1337270496655446016";			
			this.$api.news.editNewsDetail({openid,productCodes}).then((res)=>{
				alert(res.data.msg);
			})
		}
	}	
}
</script>
<style lang="scss">
#app {
 font-family: Avenir, Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
}

#nav {
 padding: 30px;

 a {
 font-weight: bold;
 color: #2c3e50;

 &.router-link-exact-active {
  color: #42b983;
 }
 }
}
</style>

Configure Agent

Because we have to test in the local environment, this involves cross-domain problems. In order to solve the cross-domain problems, we can configure the agent, create vue. config. js files in the root directory of the project, and then configure the project in various ways. The agent configuration method is as follows:


// vue.config.js
module.exports = {
 //  Output file directory 
 outputDir: "dist",
 // eslint-loader  Is it checked when saving 
 lintOnSave: false,
 //  Basic path 
 publicPath: process.env.NODE_ENV === "production" ? "./" : "/",
 devServer: {
 host: "localhost",
 port: 8080,
 open: true,
 hotOnly: true, //  Thermal renewal 
 //  Set up proxy 
 proxy: {
  "/api": {
  //  Local mock Server 
  target: "https://www.xxxx.com/xxx/",
  changeOrigin: true,
  ws: false,				
  },
  // If there are multiple domain name interfaces in the project, you can configure them in turn 
	"/apib":{
		target: "https://www.xxxx.com/xxx/",
		changeOrigin: true,
		ws: false,
	},
 }, 
 },
};

After the agent is configured, you can run the project. Enter npm run serve in the command line. After the project is started, you can enter the page and click the button to test whether the encapsulation you did before is easy to use.

Conclusion

The above is my vue encapsulation axios 1 point of experience, article errors or need to improve the place also please contact me, I will correct in time, thank you for reading.

The above is the vue encapsulation axios and api interface management details, more about vue encapsulation axios information please pay attention to other related articles on this site!


Related articles: