Vue.cli project encapsulates global axios, encapsulates requests, encapsulates public APIs and the whole process of calling requests

preface

When doing vue medium and large-scale projects, the official recommends using axios, but the native axios may not be friendly to the adaptation of the project. Therefore, encapsulate axios at the beginning of the project to maintain the unity of data processing of the whole project. This article mainly talks about how to encapsulate axios, encapsulate requests, encapsulate public APIs, and how to call requests on pages in vue cli projects.

Formal configuration route:
1. To get the project and background interface, the first thing to do is to configure the global agent and the second point.
2. Global encapsulation axios And the third point request.js. 
3. filter axios Request mode, control path and parameter format and point 4 http.js. 
4. Formal packaging api And point five api.js. 
5. Page call.
Copy code

text

1, Preliminary configuration of VUE project

Create a new vue project, Download axios, and import axios in main.js.

npm i axios -S
Copy code
// main.js
import axios from "axios"
Copy code

2, Proxy address in config file

The index.js file in the project config directory is mainly used to write and configure multiple background interfaces.

Agent configuration of vue cil2 old version -- confin/index.js

 dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    // The back-end request address proxy directly refers to testIp after configuration and subsequent page calls http://197.82.15.15:8088
    proxyTable: {
      '/testIp': {
        target: 'http://197.82.15.15:8088',
        changeOrigin: true,
        pathRewrite: { 
          '^/testIp': ''
        }
      },
      '/elseIp': {
        target: 'http://182.83.19.15:8080',
        changeOrigin: true,
        pathRewrite: { 
          '^/esleIp': ''
        }
      },
    },

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-


    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you encounter problems debugging vue files in devtools,
    // Setting this to false may help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },


Copy code

Agent configuration vue.config.js file for vue cil 3 + new version

About multi-agent configuration:

		 devServer: {
            overlay: { // Let the browser overlay display both warnings and errors
              warnings: true,
              errors: true
            },
            host: "localhost",
            port: 8080, // Port number
            https: false, // https:{type:Boolean}
            open: false, //Automatically start browser after configuration
            hotOnly: true, // Hot renewal
            // proxy: 'http://localhost:8080 '/ / configure cross domain processing. There is only one agent
            proxy: { //Configure multiple agents
                "/testIp": {
                    target: "http://197.0.0.1:8088",
                    changeOrigin: true,
                    ws: true,//websocket support
                    secure: false,
                    pathRewrite: {
                        "^/testIp": "/"
                    }
                },
                "/elseIp": {
                    target: "http://197.0.0.2:8088",
                    changeOrigin: true,
                    //ws: true,//websocket support
                    secure: false,
                    pathRewrite: {
                        "^/elseIp": "/"
                    }
                },
            }
        }

Copy code

3, Encapsulate axios instance -- request.js

Create a new utils folder in the src directory of the project, and then create a new request.js. This file mainly writes the packaging process of axios.

/****   request.js   ****/
// Import axios
import axios from 'axios'
// Use element UI message as message reminder
import { Message} from 'element-ui';
//1. Create a new axios instance,
const service = axios.create({
  // Public interface -- note that it will be discussed later
  baseURL: process.env.BASE_API,
  // The timeout unit is ms, and the timeout of 3s is set here
  timeout: 3 * 1000
})
// 2. Request interceptor
service.interceptors.request.use(config => {
  //Some processing before sending the request, such as data conversion, configuring the request header, setting the token, setting the loading, etc., and adding according to the needs
   config.data = JSON.stringify(config.data); //Data conversion, qs conversion can also be used
   config.headers = {
     'Content-Type':'application/x-www-form-urlencoded' //Configuration request header
   }
   //Note that when using token, you need to introduce cookie method or local storage method. JS cookie is recommended
   const token = getCookie('name');//You must get the token and save it before you get the token here
   if(token){
      config.params = {'token':token} //If required, it shall be carried in the parameter
      config.headers.token= token; //If required, carry it in the request header
    }
  return config
}, error => {
  Promise.reject(error)
})

// 3. Response interceptor
service.interceptors.response.use(response => {
  //Some common processing after receiving the response data and successfully closing loading, etc
  
  return response
}, error => {
   /***** Processing of abnormal response received starts*****/
  if (error && error.response) {
    // 1. Public error handling
    // 2. Handle according to the response code
    switch (error.response.status) {
      case 400:
        error.message = 'Error request'
        break;
      case 401:
        error.message = 'Unauthorized, please log in again'
        break;
      case 403:
        error.message = 'access denied'
        break;
      case 404:
        error.message = 'Request error,The resource was not found'
        window.location.href = "/NotFound"
        break;
      case 405:
        error.message = 'Request method not allowed'
        break;
      case 408:
        error.message = 'request timeout'
        break;
      case 500:
        error.message = 'Server side error'
        break;
      case 501:
        error.message = 'Network not implemented'
        break;
      case 502:
        error.message = 'network error'
        break;
      case 503:
        error.message = 'Service Unavailable'
        break;
      case 504:
        error.message = 'Network Timeout '
        break;
      case 505:
        error.message = 'http The request is not supported by version'
        break;
      default:
        error.message = `Connection error ${error.response.status}`
    }
  } else {
    // timeout handler 
    if (JSON.stringify(error).includes('timeout')) {
      Message.error('The server response timed out. Please refresh the current page')
    }
    error.message = 'Failed to connect to the server'
  }

  Message.error(error.message)
  /***** End of processing*****/
  //If error handling is not required, the above processing procedures can be omitted
  return Promise.resolve(error.response)
})
//4. Import file
export default service

Copy code

Special instructions:

The problem of data conversion is specially explained here

config.data = JSON.stringify(config.data);
config.headers = { 'Content-Type':'application/x-www-form-urlencoded'  }
const token = getCookie('name')
if(token){ 
  config.params = {'token':token} ; 
  config.headers.token= token; 
}

Copy code
  • The above codes are all requested configuration items. They are not necessary, but also by case. There are many parameters such as data/headers/params. You can communicate with the background and match whatever you need!
  • config.data = JSON.stringify(config.data) why not use qs.stringify? Because all my background wants is JSON type parameters, and QS conversion will be converted into key value pair splicing string. Of course, you need to pass string type parameters in the background, which can be converted to QS or other methods.
  • Const token = getcookie (name). This is the value of the token. Before taking it, you must send a request to get the token, and then save the cookie. The name is the name of the token you saved. Everyone's is different.
  • Config. Headers = {content type ':' application / x-www-form-urlended '} the configuration of the request header content is also different. Application / x-www-form-urlended: the form data is encoded as key/value format and sent to the server (the default format of the form submission data). You can configure your own needs according to the actual situation.
  • If an error is reported and the connection to the server fails after the final configuration, it is normal, because the server address configured in the example is a false address and needs to be replaced with your own server.

Changes to response interceptor error code return processing:

Optimized content corrected by the boss

// Response interceptor
service.interceptors.response.use(
    (response) => {
        const res = response.data
        if (response.config.responseType !== 'blob') {
            if (res.code !== 0) {
                Message({
                    message: res.msg || 'Error',
                    type: 'error',
                    duration: 3 * 1000,
                })
                return Promise.reject(new Error(res.msg || 'Error'))
            } else {
                return res
            }
        }
        return res
    },
    (error) => {
        let res = error.response
        if (error.response) {
            if (res.status == 401) {
                Vue.prototype.parentFns.portal_logout()
            }
        }
        return Promise.reject(error)
    }
)
Copy code

4, Encapsulation request -- http.js

Create a new http.js file in the utils folder under the src directory of the project. This file is mainly used to write the encapsulation process of several requests.

/****   http.js   ****/
// Import the encapsulated axios instance
import request from './request'

const http ={
    /**
     * methods: Request mode
     * url Request address 
     * params Request parameters
     */
    get(url,params){
        const config = {
            method: 'get',
            url:url
        }
        if(params) config.params = params
        return request(config)
    },
    post(url,params){
        const config = {
            method: 'post',
            url:url
        }
        if(params) config.data = params
        return request(config)
    },
    put(url,params){
        const config = {
            method: 'put',
            url:url
        }
        if(params) config.params = params
        return request(config)
    },
    delete(url,params){
        const config = {
            method: 'delete',
            url:url
        }
        if(params) config.params = params
        return request(config)
    }
}
//export
export default http

Copy code

5, Formally encapsulate the API for sending requests -- api.js

Create an API folder in the src directory of the project, and then create an api.js file in it. This file is the encapsulation process of writing the API.

Writing method 1 is suitable for classified export:

import http from '../utils/http'
// 
/**
 *   resquest Request address, for example: http://197.82.15.15:8088/request/...
 *   '/testIp'Represents the agent configured in config and index.js in Vue CIL
 */
let resquest = "/testIp/request/"

// get request
export function getListAPI(params){
    return http.get(`${resquest}/getList.json`,params)
}
// post request
export function postFormAPI(params){
    return http.post(`${resquest}/postForm.json`,params)
}
// put request
export function putSomeAPI(params){
    return http.put(`${resquest}/putSome.json`,params)
}
// delete request
export function deleteListAPI(params){
    return http.delete(`${resquest}/deleteList.json`,params)
}


Copy code

Writing method 2, suitable for all export:

import http from '../utils/http'
// 
/**
 *   resquest Request address, for example: http://197.82.15.15:8088/request/...
 *   '/testIp'Represents the agent configured in config and index.js in Vue CIL
 */
let resquest = "/testIp/request/"

// get request
export default{
 	getListAPI(params){
    	return http.get(`${resquest}/getList.json`,params)
	},
	 postFormAPI(params){
    	return http.post(`${resquest}/postForm.json`,params)
	}
}

Copy code

Note: in a project, if the background request is not the same ip but multiple IPS, you can create multiple js under the api folder to call the request.

Let's look at a problem left over before:

// Create a new axios instance
const service = axios.create({
    baseURL:process.nev.BASE_API,
    timeout:3 * 1000
})
Copy code

Before encapsulating the baseUrl of the public interface, the global variable process.env.base in webpack was used_ api, instead of directly writing ip, is also used to adapt to the situation that the api address at the time of multiple background or development is different from that at the time of release.

The above configuration environment and interface are basically set up. Let's take a look at the call

Six. How to call in vue file

Method 1:

Call the interface according to the api used -- this is applicable to the above interface classification export.

 import {getListAPI,postFormAPI, putSomeAPI, deleteListAPI} from '@/api/api'

  methods: {
      //   promise call, chain call, getList() only accepts parameters in parentheses;
      //   get does not pass parameters
      getList() {
        getListAPI().then(res => console.log(res)).catch(err => console.log(err))
      },
        //post pass parameter
      postForm(formData) {
        let data = formData
        postFormAPI(data).then(res => console.log(res)).catch(err => console.log(err))
      },

      //async await synchronous call
      async postForm(formData) {
        const postRes = await postFormAPI(formData)
        const putRes = await putSomeAPI({data: 'putTest'})
        const deleteRes = await deleteListAPI(formData.name)
        // data processing
        console.log(postRes);
        console.log(putRes);
        console.log(deleteRes);
      },
   }

Copy code

Method 2:

Import all APIs, and then call which api with which -- applicable to all exports

   import api from '@/api/api'
   methods: {
     getList() {
        api.getListAPI(data).then(res => {
          //data processing
        }).catch(err => console.log(err))
      }
    }  

Copy code

epilogue

The above is a detailed introduction to how to encapsulate axios, encapsulate requests, encapsulate public APIs, configure multiple interfaces, how to call requests on pages and other issues in Vue CIL projects. However, this encapsulation method is more suitable for medium and large-scale projects, and the configuration is more reasonable. If it is your own small project, you can directly use axios.

last

If you think this article is a little helpful to you, give it a compliment. Or you can join my development exchange group: 1025263163 learn from each other, and we will have professional technical Q & A to solve doubts

If you think this article is useful to you, please click star: http://github.crmeb.net/u/defu esteem it a favor  !

Added by mmitdnn on Mon, 29 Nov 2021 09:01:07 +0200