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

Pitfalls based on MySQL default sorting rules

The default varchar type in MySQL is case insensi...

MySQL replication detailed explanation and simple example

MySQL replication detailed explanation and simple...

Basic concepts and common methods of Map mapping in ECMAScript6

Table of contents What is a Mapping Difference be...

HTML table border control implementation code

Generally, when we use a table, we always give it...

Ubuntu16.04 builds php5.6 web server environment

Ubuntu 16.04 installs the PHP7.0 environment by d...

HTML+CSS+JS realizes the scrolling gradient effect of the navigation bar

Table of contents First look at the effect: accom...

Detailed explanation of CSS3 text shadow text-shadow property

Text shadow text-shadow property effects: 1. Lowe...

The whole process of upgrading Angular single project to multiple projects

Table of contents Preface Development Environment...

How to install MySQL server community version MySQL 5.7.22 winx64 in win10

Download: http://dev.mysql.com/downloads/mysql/ U...

Summary of how to add root permissions to users in Linux

1. Add a user . First, use the adduser command to...

Detailed explanation of how to use the vue3 Teleport instant movement function

The use of vue3 Teleport instant movement functio...

Classification of web page color properties

Classification of color properties Any color can ...

CSS beginner tutorial: background image fills the entire screen

If you want the entire interface to have a backgr...