In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "what is the encapsulation of Axios in Vue and the management method of API interface". The content of the explanation in this article is simple and clear, and it is easy to learn and understand. please follow the editor's train of thought to study and learn "what is the encapsulation of Axios in Vue and the management method of API interface".
1. Encapsulation of axios
In the vue project, we usually use the axios library, which is a promise-based http library, which can be run on the browser side and node.js. It has many excellent features, such as intercepting requests and responses, canceling requests, converting json, client defense XSRF, and so on. So our you Da also decisively gave up the maintenance of its official library vue-resource and directly recommended that we use the axios library. If you still don't know anything about axios, you can move to the axios document.
Installation
Npm install axios; / / install axios
Introduce
Normally, I will create a new request folder in the src directory of the project, and then create a new http.js and an api.js file in it. The http.js file is used to encapsulate our axios,api.js to uniformly manage our interface.
/ / introduce axios import axios from 'axios'; / / introduce axios import QS from' qs'; / / introduce qs module into http.js to serialize data of post type. The toast prompt box component of / / vant will be mentioned later, which can be changed according to your own ui component. Import {Toast} from 'vant'
Switching of environment
Our project environment may have a development environment, a test environment and a production environment. We match our default interface url prefix through the environment variable of node. Not to mention that axios.defaults.baseURL can set the default request address for axios.
/ / switch if for the environment (process.env.NODE_ENV = = 'development') {axios.defaults.baseURL =' https://www.baidu.com';} else if (process.env.NODE_ENV = = 'debug') {axios.defaults.baseURL =' https://www.ceshi.com'; } else if (process.env.NODE_ENV = = 'production') {axios.defaults.baseURL =' https://www.production.com';}
Set request timeout
Sets the default request timeout through axios.defaults.timeout. For example, if it exceeds 10s, the user will be informed that the current request timed out, please refresh, etc.
Axios.defaults.timeout = 10000
Setting of post request header
When making a post request, we need to add a request header, so we can make a default setting here, that is, set the request header of post to application/x-www-form-urlencoded;charset=UTF-8.
Axios.defaults.headers.post ['Content-Type'] =' application/x-www-form-urlencoded;charset=UTF-8'
Request intercept
We can intercept a request before sending it. Why intercept it? what do we use to intercept the request? For example, some requests require users to log in before they can be accessed, or when post requests, we need to serialize the data we submit. At this point, we can intercept the request before it is sent to do what we want.
Request intercept
/ / Import vuex first, because we need to use the path to the status object / / vuex to write import store from'@ / store/index' according to our own path. / / request interceptor axios.interceptors.request.use (config = > {/ / determine whether there is a token in the vuex before sending a request / / if so, add token to the header of the http request, so that the backend judges your login status according to the token / / even if there is a local token, it is possible that the token is expired So it is necessary to judge the return status in the response interceptor const token = store.state.token Token & (config.headers.Authorization = token); return config;}, error = > {return Promise.error (error);})
Here we talk about token. Generally, after logging in, the user's token is stored locally through localStorage or cookie, and then each time the user enters the page (that is, in main.js), the token is first read from the local storage. If the existence of token indicates that the user has logged in, the token status in the vuex is updated. Then, every time the API is requested, the token will be carried in the requested header, and the backend staff can determine whether your login has expired according to the token you carry. If you do not carry it, you have not logged in. At this time, some friends may have doubts, that is, every request carries a token, so what if a page can be accessed without a user login? In fact, your front-end request can carry token, but the backend can choose not to receive it!
Interception of response
/ / response interceptor axios.interceptors.response.use (response = > {/ / if the returned status code is 200, the API request is successful. / / otherwise, the error if (response.status = = 200) {return Promise.resolve (response) is thrown. } else {return Promise.reject (response) }}, / / the server status code does not start with 2 / / you can negotiate a unified error status code with your background developer / / and then perform some operations according to the returned status code, such as login expiration prompt, error prompt, etc. / / list a few common operations below Other requirements can be expanded error = > {if (error.response.status) {switch (error.response.status) {/ / 401: if you are not logged in / / if you are not logged in, you will jump to the login page. And take the path of the current page / / return to the current page after a successful login. This step needs to be done on the login page. Case 401: router.replace ({path:'/ login' Query: {redirect: router.currentRoute.fullPath}}) Break / / token Expiration / / Login Expiration prompt the user / / clear the local token and clear the token object in the vuex / / Redirect login page case: Toast ({ Message: 'login expired Please log in again', duration: 1000, forbidClick: true}) / / clear token localStorage.removeItem ('token'); store.commit (' loginSuccess', null) / / Jump to the login page and pass the page to be viewed by fullPath After successful login, you need to jump to the page setTimeout (()) > {router.replace ({path:'/ login') Query: {redirect: router.currentRoute.fullPath}}) }, 1000); break Case 404: Toast ({message: 'network request does not exist', duration: 1500, forbidClick: true}); break / / other errors, directly throw the error prompt default: Toast ({message: error.response.data.message, duration: 1500, forbidClick: true}) } return Promise.reject (error.response);})
The response interceptor is easy to understand, which is the data returned to us by the server, and we can do some processing on it before we get it. For example, the above idea: if the status code returned by the background is 200, the data will be returned normally, otherwise we will make some errors according to the wrong status code type. in fact, here is mainly a unified handling of the error and an operation to adjust the login page after no login or login expiration.
Note that the Toast () method above is the toast light prompt component in the vant library I introduced, and you use one of your prompt components according to your ui library.
Encapsulate get method and post method
Our commonly used ajax request methods include get, post, put and other methods, which are no stranger to our friends. There are many similar methods for axios. If you are not clear, you can take a look at the documentation. But in order to simplify our code, we still need to do a simple encapsulation. Below we mainly encapsulate two methods: get and post.
Get method: we define a get function, the get function takes two parameters, the first parameter represents the url address we want to request, and the second parameter is the request parameter we want to carry. The get function returns a promise object, and the resolve server returns the value when the axios request succeeds, and the reject error value when the request fails. Finally, the get function is thrown through export.
/ * get method Corresponding to the get request * @ param {String} url [requested url address] * @ param {Object} params [parameters carried during the request] * / export function get (url, params) {return new Promise ((resolve, reject) = > {axios.get (url) {params: params}) .then (res = > {resolve (res.data)) ) .catch (err = > {reject (err.data)})});}
* * post method: * * the principle is basically the same as get, but note that the post method must use the operation to serialize the commit from the parameter object, so here we serialize our parameters through node's qs module. This is very important, if there is no serialization operation, the background will not get the data you submitted. This is why we import QS from 'qs'; at the beginning of the article. If you don't understand what serialization means, Baidu has a lot of answers.
/ * post method, corresponding to the post request * @ param {String} url [requested url address] * @ param {Object} params [parameters carried during the request] * / export function post (url, params) {return new Promise ((resolve, reject) = > {axios.post (url, QS.stringify (params)) .then (res = > {resolve (res.data)) ) .catch (err = > {reject (err.data)})});}
Here is a small detail: there is a difference between the axios.get () method and axios.post () in the way parameters are written when submitting data. The difference is that the second parameter of get is a {}, and then the value of the params property of this object is the value of a parameter object. The second parameter of post is a parameter object. Pay attention to the slight difference between the two!
The encapsulation of axios is basically completed, so let's briefly talk about the unified management of api.
A neat api is like a circuit board, no matter how complex it is, it can make the whole circuit clear. As mentioned above, we will create a new api.js and store all our api interfaces in this file.
First of all, we introduce our encapsulated get and post methods into api.js
/ * * Unified Management of api API * / import {get, post} from'. / http'
Now, for example, we have an interface that is a post request:
Http://www.baiodu.com/api/v1/users/my_address/address_edit_before
We can encapsulate it like this in api.js:
Export const apiAddress = p = > post ('api/v1/users/my_address/address_edit_before', p)
We define an apiAddress method that has one parameter, pforce p, which is the parameter object we carry when we request the interface. Then we call our encapsulated post method. The first parameter of the post method is our interface address, and the second parameter is the p parameter of apiAddress, which is the parameter object carried when the interface is requested. Finally, export apiAddress through export.
Then in our page, we can call our api interface like this:
Import {apiAddress} from'@ / request/api';// imports our api interface export default {name: 'Address', created () {this.onLoad () }, methods: {/ / get data onLoad () {/ / call the api API And provide two parameters apiAddress ({type: 0, sort: 1}). Then (res = > {/ / other operations after getting the data successfully … })}
For other api interfaces, just continue to expand below in pai.js. Friendly tips, write notes for each interface!
One of the advantages of api interface management is that we centralize the api. If we need to modify the interface later, we can just find the corresponding modification in api.js, instead of going to every page to find our interface and then modify it will be very troublesome. The key is, in case the amount of modification is relatively large, the specification will be gg. In addition, if we modify the interface directly in our business code, it is easy to touch our business code and cause unnecessary trouble.
All right, finally, the completed axios package code is presented.
/ * * axios encapsulation * request interception, corresponding interception, error unified handling * / import axios from 'axios';import QS from' qs'; import {Toast} from 'vant'; import store from'.. / store/index' / / handover if of the environment (process.env.NODE_ENV = = 'development') {axios.defaults.baseURL =' / api' } else if (process.env.NODE_ENV = = 'debug') {axios.defaults.baseURL =';} else if (process.env.NODE_ENV = = 'production') {axios.defaults.baseURL =' http://api.123dailu.com/';} / / request timeout axios.defaults.timeout = 10000; / / post request header axios.defaults.headers.post ['Content-Type'] =' application/x-www-form-urlencoded Charset=UTF-8' / / request interceptor axios.interceptors.request.use (config = > {/ / determine whether a token exists before sending a request. If so, add token to the header of the http request without manually adding / / even if there is a local token, it is possible that the token is expired. So it is necessary to judge the return status in the response interceptor const token = store.state.token Token & (config.headers.Authorization = token); return config;}, error = > {return Promise.error (error) ) / / response interceptor axios.interceptors.response.use (response = > {if (response.status = 200) {return Promise.resolve (response);} else {return Promise.reject (response)) }} / / if the server status code is not 200, error = > {if (error.response.status) {switch (error.response.status) {/ / 401: if you are not logged in / / if you are not logged in, jump to the login page And take the path of the current page / / return to the current page after a successful login. This step needs to be done on the login page. Case 401: router.replace ({path:'/ login', query: {redirect: router.currentRoute.fullPath}}); break / / token Expiration / / Login Expiration prompt the user / / clear the local token and clear the token object in the vuex / / Redirect login page Case 403: Toast ({message: 'login expired Please log in again', duration: 1000, forbidClick: true}) / / clear token localStorage.removeItem ('token'); store.commit (' loginSuccess', null) / / Jump to the login page and pass the page to be viewed by fullPath After successful login, you need to jump to the page setTimeout (()) > {router.replace ({path:'/ login') Query: {redirect: router.currentRoute.fullPath}}) }, 1000); break / / case 404: Toast ({message: 'network request does not exist', duration: 1500) ForbidClick: true}) Break / / other errors Directly throw the error prompt default: Toast ({message: error.response.data.message, duration: 1500) ForbidClick: true}) } return Promise.reject (error.response);}) / * get method Corresponding to the get request * @ param {String} url [requested url address] * @ param {Object} params [parameters carried during the request] * / export function get (url, params) {return new Promise ((resolve, reject) = > {axios.get (url) {params: params}) .then (res = > {resolve (res.data)) }) .catch (err = > {reject (err.data)})}) } / * * post method Corresponding to the post request * @ param {String} url [requested url address] * @ param {Object} params [parameters carried during the request] * / export function post (url, params) {return new Promise ((resolve, reject) = > {axios.post (url, QS.stringify (params)) .then (res = > {resolve (res.data)) ) .catch (err = > {reject (err.data)})});}
If you like, give me a ❤❤ (* ^ ▽ ^ *)
* gorgeous dividing line *
Update on August 14, 2018
The encapsulation of axios varies according to different requirements. Thank you very much for some pertinent suggestions in the comments. I have also thought about it and improved it according to different needs. The main changes are as follows:
1. Optimize axios encapsulation to remove previous get and post
two。 Handling of network disconnection
3. More modular api management
4. There are multiple interface domain names.
5.api mounting to vue.prototype omits the steps of introduction
For the optimization of axios encapsulation in http.js, paste the code directly:
/ * axios encapsulation * request interception, response interception, error unified handling * / import axios from 'axios'; import router from'.. / router'; import store from'.. / store/index'; import {Toast} from 'vant' / * * prompt function * disable clicking on mask, close after displaying for one second * / const tip = msg = > {Toast ({message: msg, duration: 1000, forbidClick: true}) } / * Jump login page * carries the current page route to return to the current page after the login page has completed login * / const toLogin = () = > {router.replace ({path:'/ login', query: {redirect: router.currentRoute.fullPath}}) Error uniform handling after failed request * @ param {Number} status code of failed status request * / const errorHandle = (status, other) = > {/ / status code to judge switch (status) {/ / 401: unlogged status, jump to login page case: toLogin (); break / / token expired / / clear token and jump to login page case 403: tip ('login expired, please log in again'); localStorage.removeItem ('token'); store.commit (' loginSuccess', null); setTimeout (() = > {toLogin ();}, 1000) Break; / / 404 request does not exist case 404: tip ('requested resource does not exist'); break; default: console.log (other);}} / / create axios instance var instance = axios.create ({timeout: 1000 * 12}) / / set the post request header instance.defaults.headers.post ['Content-Type'] =' application/x-www-form-urlencoded' / * * request interceptor * before each request, if there is a token, carry token * / instance.interceptors.request.use in the request header (config = > {/ / in the login process control, judge the login status of the user according to whether the local token exists / / but even if the token exists, it is possible that the token is expired. So carry token / / in each request header to judge the login status of the user according to the token carried, and return to us the corresponding status code / /, then we can do some unified operations according to the status code in the response interceptor. Const token = store.state.token; token & & (config.headers.Authorization = token); return config;}, error = > Promise.error (error) / / response interceptor instance.interceptors.response.use (/ / request succeeded res = > res.status = 200? Promise.resolve (res): Promise.reject (res), / / request failed error = > {const {response} = error; if (response) {/ / the request has been issued but is not within the scope of 2xx errorHandle (response.status, response.data.message); return Promise.reject (response) } else {/ / handle network outage / / eg: update the network status of state / / network status in app.vue to control the display and hiding of a global disconnection prompt component / / about refresh in the disconnection component to retrieve data when a request is timed out or disconnected If (! window.navigator.onLine) {store.commit ('changeNetwork', false) is specified in the disconnected component } else {return Promise.reject (error);}); export default instance
This axios is more or less the same as the previous one, with the following changes:
1. It removes the wrapper of the previous get and post methods and makes it more flexible to use by creating an instance of axios and exporting it with the export default method.
two。 The value of controlling baseUrl through environment variables is removed. Considering that the interface will have multiple different domain names, you are going to use the js variable to control the interface domain name. This point will be introduced in api.
3. Increased request timeout, that is, off-network state processing. To talk about the train of thought, when the network is cut off, the display and concealment of the disconnection prompt component can be controlled by updating the status of network in vuex. The disconnection prompt will generally have the operation of reloading data, which will be described in the corresponding place later.
4. Common functions are extracted to simplify the code and ensure the principle of single responsibility as far as possible.
Let's talk about api, taking into account the requirements:
1. More modular
two。 More convenient for multi-person development, effectively reducing the resolution of naming conflicts
3. There are several situations for dealing with interface domain names
Here, a new api folder is created, which contains an index.js and a base.js, as well as several interface js files divided according to the module. Index.js is an exit to api, base.js manages the interface domain name, and other js is used to manage the interfaces of each module.
Put the index.js code first:
/ * * Unified exit of api interface * / / article module interface import article from'@ / api/article'; / / other module interface. / / Export interface export default {article, / /. }
Index.js is the exit of an api interface, so the api interface can be divided into multiple modules according to its function, which is conducive to collaborative development. For example, one person is only responsible for the development of one module, and it is also convenient to name the interfaces in each module.
Base.js: / * Management of interface domain name * / const base = {sq: 'https://xxxx111111.com/api/v1', bd:' http://xxxxx22222.com/api'} export default base
Manage our interface domain name through base.js, no matter how many interfaces can be defined here. Even if it is modified, it is still very convenient.
Finally, there is a description of the interface module, such as the article.js above:
/ * * article module interface list * / import base from'. / base'; / / Import interface domain name list import axios from'@ / utils/http'; / / Import axios instance import qs from 'qs' created in http / / Import qs module const article = {/ / News list articleList () {return axios.get (`${base.sq} / topics`) according to the demand }, / / News details, demo articleDetail (id, params) {return axios.get (`${base.sq} / topic/$ {id}`, {params: params}) }, / / post submit login (params) {return axios.post (`${base.sq} / uplostoken`, qs.stringify (params));} / / other APIs. } export default article
1. By directly introducing our encapsulated axios instance, and then defining the interface, calling the axios instance and returning it, you can use axios more flexibly, for example, you can perform a qs serialization of the data submitted during the post request.
two。 The configuration of the request is more flexible, and you can make a different configuration for a particular requirement. With regard to the priority of the configuration, the axios documentation makes it clear that the order is the default value of the library found in lib/defaults.js, then the defaults property of the instance, and finally the config parameter of the request. The latter will take precedence over the former.
3.restful style interface, you can also set the api interface address flexibly in this way.
Finally, in order to facilitate the call to api, we need to mount it to the prototype of vue. In main.js:
Import Vue from 'vue' import App from'. / App' import router from'. / router' / / Import routing file import store from'. / store' / / Import vuex file import api from'. / api' / / Import api interface Vue.prototype.$apiapi = api; / / Mount api to the prototype of vue
Then we can call the interface in the page like this, eg:
Methods: {onLoad (id) {this.$api.article.articleDetail (id, {api: 123}) .then (res= > {/ / perform some actions})}}
When it comes to the handling of network outage, here is only a simple example:
I don't have the Internet. Refresh import {mapState} from 'vuex'. Export default {name: 'App', computed: {... mapState ([' network'])} Methods: {/ / refresh the current page data onRefresh () {this.$router.replace ('/ refresh')} by jumping to an empty page and returning it.
This is app.vue, here is a brief demonstration of disconnection. As described in http.js, we will update the status of network in vue when the network is disconnected, so here we determine whether the disconnected component needs to be loaded based on the status of network. In the case of network disconnection, the disconnected components are loaded, but the components of the corresponding pages are not loaded. When we click Refresh, we retrieve the data by jumping to the refesh page and returning immediately. So we need to create a new refresh.vue page and return to the current page in its beforeRouteEnter hook.
/ / refresh.vue beforeRouteEnter (to, from, next) {next (vm = > {vm.$router.replace (from.fullPath)})}
This is a global downtime prompt, of course, according to your own project requirements. According to the specific operation, the benevolent people have their own opinions.
If there are more requirements, or different requirements, you can make an improvement according to your own needs.
Thank you for reading, the above is "what is the encapsulation of Axios in Vue and the management method of API interface?" after the study of this article, I believe you have a deeper understanding of the encapsulation of Axios in Vue and what the management method of API interface is, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.