How to encapsulate axios in Vue

How to encapsulate axios in Vue

1. Installation

npm install axios; // Install axios

1. Introduction

import axios from 'axios'

3. Interface root address

const baseUrl = API_BASE_URL // Injected into webpackConfig by webpack's plugin DefinePlugin
    .plugin('define')
        .use(require('webpack/lib/DefinePlugin'), [{
            // NODE_ENV environment variable, the development environment is: 'development', in order to ensure that the package of the test environment is consistent with the production environment, the test environment and the production environment are both 'production'
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
            // The current application environment (development environment: 'dev', test environment: 'test', production environment: 'prod')
            'process.env.APP_ENV': JSON.stringify(process.env.APP_ENV),
            //Backend interface request address 'API_BASE_URL': JSON.stringify(config.meshProp('apiBaseUrl')),
            // Home page path 'APP_INDEX_PATH': JSON.stringify(indexPath),
            // Routing mode 'APP_ROUTER_MODE': JSON.stringify(config.meshProp('routerMode')),
            // Whether to use the Element component library 'APP_USE_ELEMENT': JSON.stringify(config.meshProp('useElement')),

}])


config.js : configure some system names, api root paths, etc.

const path = require('path')
const os = require('os')
const packageName = 'focm' // Project package name const localIP = getLocalIP() // Local IP address module.exports = {
    //Default configuration default: {
        // System name, used to set the title in the page header
        appName: 'xxxxx',
        // Is it a multi-page application isMulti: false,
        // Whether to support mobile terminal isMobile: false,
        // Whether to use the Element component library (https://element.eleme.cn/#/zh-CN/)
        useElement: true,
        // Routing mode (value is hash or history, reference: https://router.vuejs.org/)
        routerMode: 'hash',
        // API request root path apiBaseUrl: '',
        ....
    },
    // Development environment configuration dev: {
        apiBaseUrl: '/api',
        host: localIP,
        port: 8080,
        autoOpenBrowser: true, // Whether to automatically open the browser writeToDisk: false, // Whether to write the generated file to the disk proxyTable: {
            '/api': {
                target: 'http://focm-web.focms.paas.test',
                changeOrigin: true
                }
            }
    },
    // Test environment configuration test: {
        // API request root path apiBaseUrl: '/focm',
        outputRoot: path.resolve(__dirname, 'dist/test'),
        publish: {
            remoteHost: 'xxxx',
            remotePort: '22',
            remoteUsername: 'qinglianshizhe',
            remotePassword: 'xxxxxx',
            remoteAppRoot: `/xxx/xxx/${packageName}`,
            webUrl: 'http://xxxxx.com/'
        }
    },
    // Configuration of production environment prod: {
        ...
    }
}

// Get the local IP
function getLocalIP () {
    let interfaces = os.networkInterfaces()
    for(let devName in interfaces){
        let iface = interfaces[devName]
        for(let i=0;i<iface.length;i++){
            let alias = iface[i];
            if(alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal){
                return alias.address;
            }
        }
    }
    return 'localhost'
}

Let's continue to encapsulate axios

/**
 * Business exception class */

class BusinessError extends Error {
    constructor (code, message, data) {
        super(message)
        this.code = code
        this.name = 'BusinessError'
        this.data = data
    }
}
/**
 * System exception class */
class SystemError extends Error {
    constructor (code, message, data) {
        super(message)
        this.code = code
        this.name = 'SystemError'
        this.data = data
    }
}
// axios configuration axios.defaults.timeout = 10000
axios.defaults.headers.post['Content-Type'] = 'application/json; charset=UTF-8'

// Execute POST request function post (option, vm) {
    option.method = 'POST'
    return http(option, vm)
}

// Execute GET request function get (option, vm) {
    option.method = 'GET'
    return http(option, vm)
}

// Download request function download (option, vm) {
    option.method = option.method || 'GET'
    option.isDownload = true
    option.responseType = 'blob'
    return http(option, vm)
    }

/**
* Request backend interface* @param option parameter* url: request path (will be spliced ​​after baseUrl, starting with “/”)
* data: request parameter object * timeout: request timeout (default: 10000, i.e. 10 seconds)
* toastError: Automatically prompt business exception information, the default is true, no automatic prompt when false * @param vm Vue object (used for automatic toast prompt exception information when an exception occurs)
* @return {Promise} Promise object */

function http (option, vm) {
    return new Promise((resolve, reject) => {
        let method = option.method || 'POST'
        let url = baseUrl + option.url
        let timeout = option.timeout || 10000
        let headers = option.headers || {}
        let responseType = option.responseType
        let data = {} // You can set the default value here if (option.data) {
            if (option.data instanceof FormData) {
                headers['Content-Type'] = 'multipart/form-data'
                let formData = option.data
                Object.keys(data).forEach((key) => {
                    formData.append(key, data[key])
                })
                data = formData
            } else {
                data = { ...data, ...option.data }
            }
        }

        let requestOptions = { method, url, headers, timeout, responseType }
        if (method.toUpperCase() === 'GET') {
            requestOptions.params = data
        } else {
            requestOptions.data = data
        }
        axios(requestOptions).then( (res) => {
            const contentDisposition = res.headers['content-disposition']
            // File download if (contentDisposition &&
        (/filename\*=UTF-8''(.*)/.test(contentDisposition) || /filename="(.*)"/.test(contentDisposition))) { // If it is a file download const utf8Match = contentDisposition.match(/filename\*=UTF-8''(.*)/) // Match UTF-8 file name const normalMatch = contentDisposition.match(/filename="(.*)"/) // Match ordinary English file name const filename = utf8Match ? decodeURIComponent(utf8Match[1]) : normalMatch[1]
                const blob = new Blob([res.data])
                const downloadElement = document.createElement('a')
                const href = window.URL.createObjectURL(blob)
                downloadElement.href = href
                downloadElement.download = filename
                document.body.appendChild(downloadElement)
                downloadElement.click()
                document.body.removeChild(downloadElement)
                window.URL.revokeObjectURL(href)
                resolve(res)
            } else { // JSON information getResponseInfo(res).then((resInfo) => {
                    responseInfoHandle(resInfo, resolve, reject, option, vm, requestOptions)
                })
            }
        }, err => {
            errorhandle(err, reject, option, vm)
        }).catch(function (err) {
            errorhandle(err, reject, option, vm)
        })
    })

}

// Process response information function responseInfoHandle (resInfo, resolve, reject, option, vm) {
    // Is the request successful? let isSuccess = resInfo.retCode === '200'
    // Status code let code = resInfo.retCode
    // Description information let message = resInfo.retMsg || 'Request failed! '
    // data let resData = resInfo.data || {}
    if (isSuccess) { // Request successfulconsole.log(`[${option.method || 'POST'}]${option.url} Request successful!\nRequest parameters:`, option.data, '\nResponse result:', resInfo)
        resolve(resData)
    } else { // Business exception console.error(`[${option.method} || 'POST']${option.url} Request failed!\nRequest parameters:`, option.data, '\nResponse result:', resInfo)
        let err = new BusinessError(code, message, resData)
        errorhandle(err, reject, option, vm)
    }
}

// Get the response information json object function getResponseInfo (res) {
    return new Promise((resolve, reject) => {
        // Returned information let resInfo = res.data
        if (resInfo instanceof Blob) {
            const reader = new FileReader()
            reader.readAsText(resInfo, 'utf-8')
            reader.onload = () => {
                resInfo = JSON.parse(reader.result)
                resolve(resInfo)
            }
        } else {
        resolve(resInfo)
        }
    })
}

/* Exception handling */
function errorhandle (err, reject, option, vm) {
    let error = null
    if (err.name === 'BusinessError') {
        error = err
    } else {
        console.error(option.url, 'Request failed!', err.code, err)
        error = new SystemError(500, 'Sorry, a system error occurred. Please try again later!')
    }
    console.log('error = ', error)
    if (vm) {
        if (error.name === 'BusinessError') { // Business exception // No permission if (error.code === 'xxx') {
                error.ignore = true
                if (!isShowUnauthorized) {
                    vm.$popupAlert({
                        title: 'Tips',
                        message: 'Not logged in or session has expired, please log in again! ',
                        width: 330,
                        height: 180,
                        btnText: 'Log in again',
                        onOK: () => {
                            isShowUnauthorized = false // Whether to display the re-login pop-up box set to true
                            // Jump to the login page. After successful login, jump to the original path vm.$router.push({ name: 'login', params: { fromPath: vm.$route.fullPath } })
                            vm.$eventBus.$emit('NO_AUTH_EVENT')
                        }
                    })
                    isShowUnauthorized = true // Whether to display the re-login pop-up box set to true
                }
                error.ignore = true
            } else if (option.toastError !== false) {
                vm.$toast({ type: 'error', message: error.message })
            }
        } else { // System abnormality vm.$toast('Network abnormality!')
        }
    }
    reject(error)
}

export default {
    baseUrl,
    http,
    post,
    get,
    download
}

apiPlugin.js , encapsulated as plugin

import Vue from 'vue'
import api from '@/assets/js/api.js'

export default {
    install () {
        Vue.prototype.$api = api
    }
}

main.js, inject plugin

import ApiPlugin from './plugins/apiPlugin.js'

//Backend interface plug-in Vue.use(ApiPlugin)

4. Usage Examples

4.1 Download

this.$api.download({
    url: '/xxx/xxx/xxx',
    data:params
}, this)

4.2get

this.$api.get({
    url: `/xxx/xxx/xx`,
    data:params
}, this).then((res) => {
    console.log(res)
})

4.3post

this.$api.post({
    url: '/api/basicList/query',
    data:params
}, this).then(res => {
})

At this point, the encapsulation of axios is basically completed

This is the end of this article about how to encapsulate axios in Vue. For more information about encapsulating axios in Vue, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed example of using typescript to encapsulate axios in Vue3
  • How to simply encapsulate axios in vue
  • How to encapsulate axios request with vue
  • Several ways to encapsulate axios in Vue
  • Detailed explanation of AXIOS encapsulation in Vue

<<:  How to communicate between WIN10 system and Docker internal container IP

>>:  The contents of the table in HTML are displayed horizontally and vertically in the center

Recommend

Detailed summary of web form submission methods

Let's first look at several ways to submit a ...

Several CSS3 tag shorthands (recommended)

border-radius: CSS3 rounded corners Syntax: borde...

MySQL encryption and decryption examples

MySQL encryption and decryption examples Data enc...

Project practice of deploying Docker containers using Portainer

Table of contents 1. Background 2. Operation step...

25 Examples of News-Style Website Design

bmi Voyager Pitchfork Ulster Grocer Chow True/Sla...

Vue implements the method example of tab routing switching component

Preface This article introduces the use of vue-ro...

Detailed example of using if statement in mysql stored procedure

This article uses an example to illustrate the us...

Deep understanding of the use of ::before/:before and ::after/:after

Part 1: Basics 1. Unlike pseudo-classes such as :...

Implementation of built-in modules and custom modules in Node.js

1. Commonjs Commonjs is a custom module in nodejs...

Implementing circular scrolling list function based on Vue

Note: You need to give the parent container a hei...

CSS3 to achieve floating cloud animation

Operation effect html <head> <meta chars...

A complete list of meta tag settings for mobile devices

Preface When I was studying the front end before,...