千家信息网

在Vue中是怎样进行封装axios

发表于:2024-11-18 作者:千家信息网编辑
千家信息网最后更新 2024年11月18日,今天就跟大家聊聊有关在Vue中是怎样进行封装axios,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、安装npm install axios
千家信息网最后更新 2024年11月18日在Vue中是怎样进行封装axios

今天就跟大家聊聊有关在Vue中是怎样进行封装axios,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

1、安装

npm install axios; // 安装axios

1、引入

import axios from 'axios'

3、接口根地址

const baseUrl = API_BASE_URL // 由webpack的插件DefinePlugin注入webpackConfig    .plugin('define')        .use(require('webpack/lib/DefinePlugin'), [{            // NODE_ENV 环境变量,开发环境为: 'development', 为了保证测试环境打的包与生产环境一致,测试环境和生产环境都为'production'            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),            // 当前应用的环境(开发环境为: 'dev',测试环境为: 'test', 生产环境为: 'prod')            'process.env.APP_ENV': JSON.stringify(process.env.APP_ENV),            // 后台接口请求地址            'API_BASE_URL': JSON.stringify(config.meshProp('apiBaseUrl')),            // 首页路径            'APP_INDEX_PATH': JSON.stringify(indexPath),            // 路由模式            'APP_ROUTER_MODE': JSON.stringify(config.meshProp('routerMode')),            // 是否使用Element组件库            'APP_USE_ELEMENT': JSON.stringify(config.meshProp('useElement')),}])

config.js:配置一些系统名称,api根路径等

const path = require('path')const os = require('os')const packageName = 'focm' // 项目包名称const localIP = getLocalIP() // 本地IP地址module.exports = {    // 默认配置    default: {        // 系统名称,用于设置页面 head 中 title        appName: 'xxxxx',        // 是否为多页应用        isMulti: false,        // 是否支持移动端        isMobile: false,        // 是否使用Element组件库(https://element.eleme.cn/#/zh-CN/)        useElement: true,        // 路由模式(值为hash 或 history, 参考:https://router.vuejs.org/)        routerMode: 'hash',        // 接口请求根路径        apiBaseUrl: '',        ....    },    // 开发环境的配置    dev: {        apiBaseUrl: '/api',        host: localIP,        port: 8080,        autoOpenBrowser: true, // 是否自动打开浏览器        writeToDisk: false, // 是否将生成的文件写入磁盘        proxyTable: {            '/api': {                target: 'http://focm-web.focms.paas.test',                changeOrigin: true                }            }    },    // 测试环境的配置    test: {        // 接口请求根路径        apiBaseUrl: '/focm',        outputRoot: path.resolve(__dirname, 'dist/test'),        publish: {            remoteHost: 'x.x.x.x',            remotePort: '22',            remoteUsername: 'qinglianshizhe',            remotePassword: 'xxxxxx',            remoteAppRoot: `/xxx/xxx/${packageName}`,            webUrl: 'http://xxxxx.com/'        }    },    // 生产环境的配置    prod: {        ...    }}// 获取本地IPfunction getLocalIP () {    let interfaces = os.networkInterfaces()    for(let devName in interfaces){        let iface = interfaces[devName]        for(let i=0;i

我们继续来封装axios

/** * 业务异常类 */class BusinessError extends Error {    constructor (code, message, data) {        super(message)        this.code = code        this.name = 'BusinessError'        this.data = data    }}/** * 系统异常类 */class SystemError extends Error {    constructor (code, message, data) {        super(message)        this.code = code        this.name = 'SystemError'        this.data = data    }}// axios 配置axios.defaults.timeout = 10000axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'// 执行 POST 请求function post (option, vm) {    option.method = 'POST'    return http(option, vm)}// 执行 GET 请求function get (option, vm) {    option.method = 'GET'    return http(option, vm)}// 下载请求function download (option, vm) {    option.method = option.method || 'GET'    option.isDownload = true    option.responseType = 'blob'    return http(option, vm)    }/*** 请求后台接口* @param option 参数* url: 请求路径(会拼接到baseUrl后面,"/" 开头)* data: 请求参数对象* timeout: 请求超时时间(默认为:10000,即10秒)* toastError: 自动提示业务异常信息,默认为true,为false时不自动提示* @param vm Vue对象(用于异常时自动toast提示异常信息)* @return {Promise} Promise对象*/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 = {} // 可以在此设置默认值        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']            // 文件下载            if (contentDisposition &&        (/filename\*=UTF-8''(.*)/.test(contentDisposition) || /filename="(.*)"/.test(contentDisposition))) { // 如果是文件下载                const utf8Match = contentDisposition.match(/filename\*=UTF-8''(.*)/) // 匹配UTF-8的文件名                const normalMatch = contentDisposition.match(/filename="(.*)"/) // 匹配普通英文文件名                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信息                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)        })    })}// 处理响应信息function responseInfoHandle (resInfo, resolve, reject, option, vm) {    // 请求是否成功    let isSuccess = resInfo.retCode === '200'    // 状态码    let code = resInfo.retCode    // 描述信息    let message = resInfo.retMsg || '请求失败!'    // 数据    let resData = resInfo.data || {}    if (isSuccess) { // 请求成功        console.log(`[${option.method || 'POST'}]${option.url} 请求成功!\n请求参数:`, option.data, '\n响应结果:', resInfo)        resolve(resData)    } else { // 业务异常        console.error(`[${option.method} || 'POST']${option.url} 请求失败!\n请求参数:`, option.data, '\n响应结果:', resInfo)        let err = new BusinessError(code, message, resData)        errorhandle(err, reject, option, vm)    }}// 获取响应信息json对象function getResponseInfo (res) {    return new Promise((resolve, reject) => {        // 返回的信息        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)        }    })}/* 异常处理 */function errorhandle (err, reject, option, vm) {    let error = null    if (err.name === 'BusinessError') {        error = err    } else {        console.error(option.url, '请求失败!', err.code, err)        error = new SystemError(500, '非常抱歉,系统出现错误,请稍后重试!')    }    console.log('error = ', error)    if (vm) {        if (error.name === 'BusinessError') { // 业务异常            // 没有权限            if (error.code === 'xxx') {                error.ignore = true                if (!isShowUnauthorized) {                    vm.$popupAlert({                        title: '提示',                        message: '未登录或者会话已过期,请重新登录!',                        width: 330,                        height: 180,                        btnText: '重新登录',                        onOK: () => {                            isShowUnauthorized = false // 是否显示重新登录弹框设为true                            // 跳转到登录页面,登录成功后还跳转到原路径                            vm.$router.push({ name: 'login', params: { fromPath: vm.$route.fullPath } })                            vm.$eventBus.$emit('NO_AUTH_EVENT')                        }                    })                    isShowUnauthorized = true // 是否显示重新登录弹框设为true                }                error.ignore = true            } else if (option.toastError !== false) {                vm.$toast({ type: 'error', message: error.message })            }        } else { // 系统异常            vm.$toast('网络异常!')        }    }    reject(error)}export default {    baseUrl,    http,    post,    get,    download}

apiPlugin.js,封装成plugin插件

import Vue from 'vue'import api from '@/assets/js/api.js'export default {    install () {        Vue.prototype.$api = api    }}

main.js,注入插件

import ApiPlugin from './plugins/apiPlugin.js'// 后台接口插件Vue.use(ApiPlugin)

4、使用事例

4.1下载

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 => {})

到这里axios的封装基本就完成了

看完上述内容,你们对在Vue中是怎样进行封装axios有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

0