如何在Vue项目中使用axios请求

在实际的项目中,和后台的数据交互是少不了的,我通常使用的是 axios 库,所以以下示例也是以 axios 为基础来进行封装的。

1、安装

首先是 npm 安装 axios 很简单:npm install axios

2、没有封装存在的问题

如果在没有封装接口的项目中,在文件中随处可以看到如下的接口调用方法:

this.$axios.post("/user/add", {
    params: {
        name: this.name,
        age: this.age
    }
})
.then(res => {
    console.log(res)
})
.then(err => {
    console.log(res)
})

这样写不是不可以,但是存在一些缺陷,接口请求的 url 散布在各个文件中,如果需要在接口调用成功或失败时做一些处理,就需要更改每个文件。所以把这些接口请求统一集中起来,如果有调整,直接在集中文件中找到修改就好了,而不用再去查每个文件。

3、创建文件

首先在项目的 src 目录中,新建文件夹及文件目录结构如下:

├── src 源码目录

│ ├── apis 接口文件目录

│ │ ├── login.api.js 登录模块的接口 api

│ │ └── user.api.js 用户模块的接口 api

│ ├── services 请求相关文件目录

│ │ ├── address.js 请求地址配置文件

│ │ └── request.js axios封装,请求拦截、响应码处理等操作

api接口文件模块的划分,大可以根据自己的实际项目,按业务功能或业务逻辑或其他形式划分。

4、请求地址配置

一般我们的项目环境都会有多个,少的也会有开发环境和生产环境。正常情况下,在开发环境下和生产模式下有着不同的 baseURL,所以,我们需要根据不同的环境切换不同的 baseURL。

address.js 文件:

// 根据 process.env.NODE_ENV 切换不同的 baseURL
const isPro = process.env.NODE_ENV === 'production'
​
module.exports = {
    // 'apis':vue.config.js中proxy设置的代理
    baseURL: isPro ? 'http://192.168.100.120/ceds' : '/apis'
}

5、axios 配置,设置请求头及响应码处理

大体思路是通过封装一个request类,其中包含了get、post等请求方法,这些请求方法又都会去调用 request 方法,该方法通过传入的不同参数调用原始的 axios 请求,然后返回一个 Promise。

request.js 文件:

import axios from 'axios'
import Qs from 'qs'
import Vue from 'vue'
import { getToken } from '@Utils/session.utils' // 存储获取token文件
import address from './address' // 请求地址
​
class Request {
    constructor () {
        // 创建axios实例
        this._axios = axios.create({
            baseURL: address.baseURL,
            timeout: 1000 * 5, // 请求超时时间
            headers: {}
        })
        // 请求拦截
        this._axios.interceptors.request.use(
            config => {
                const requestHeader = {
                    'X-Requested-With': 'XMLHttpRequest',
                    'Content-Type': 'application/json; charset=UTF-8',
                    'Access-Control-Allow-Origin': '*',
                    token: getToken() // 请求头统一添加token
                }
                config.headers = Object.assign(config.headers, requestHeader)
                return config
            },
            error => {
                Promise.reject(error)
            }
        )
    }

    // 根据请求方式,判断参数是放在query中还是body中。
    // 最直观的区别,比如GET请求把参数包含在url中,而POST则通过request body把参数放置在body体中,所以在提交时的参数形式是有区别的
    // 以下列了四种我一般常用请求方式的参数形式,大家可以自行调整
    /**
      * 发送get请求
      * @param {String} url地址
      * @param {Object} query 查询参数
      * @return json数据
      */
    get (url, query = {}) {
        return this._request('get')(url, {
            ...query
        })
    }
    /**
      * 发送post请求
      * @param {String} url地址
      * @param {Object} body 查询参数
      * @return json数据
      */
    post(url, body = {}, headers) {
        let data;
        if(this.isFormData(body)) {
            data = body
        } else if(Array.isArray(body)) {
            data = body
        } else {
            data = { ...body }
        }
        return this._request('post')(url, headers)(url, data);
    }
    put (url, body = {}) {
        return this._request('put')(url, {
            ...body
        });
    }
    delete(url, body = {}) {
        return this._request('delete')(url, {
            ...body
        });
    }
​
    isFormData = v => {
        return Object.prototype.toString.call(v) === '[object FormData]'
    }
​
​
    /**
      * 设置请求头
      * @param {Object} header 请求头
      */
    setHeaders (header) {
        Object.keys(header).forEach(key => {
            this._axios.defaults.headers[key] = header[key]
        })
    }
​
    // 处理请求头 headers
    handleHeaders () {
        const headers = {}
        headers['XMIME-TYPE'] = '3'
        Headers['Content-Type'] = 'application/json; charset=UTF-8'
        return headers
    }
​
    /**
      * 发送请求
      * @param {String} method 请求方法类型
      * @param headers
      * @returns {function(*=, *=):Promise<unknown>}
      * @private
      */
    _request (method, headers) {
        this.setHeaders(this.handleHeaders()) // 设置统一的请求头
        if (headers) {
            this.setHeaders(headers) // 自定义请求头
        }

        return (url, data, timeout) => {
            const config = {
                url,
                method,
                timeout: timeout || this._axios.defaults.timeout
            } // 构造请求 config
​
            // 判断请求类型 get post
            const paramType = ['get', 'delete'].indexOf(method) !== -1 ? 'params' : 'data'
            config[paramType] = data
            //参数序列化
            config.paramsSerializer = params => {
                return Qs.stringify(params, { arrayFormat: 'repeat' });
            }

            return new Promise((resolve, reject) => {
                // 发送真正的请求,验证权限,检查404等status
                this._axios
                    .request(config)
                    .then(response => {
                        if (this.handleSuccessStatus(response.data.code, response.data)) {
                            if (response.headers['content-type'] !== 'text/plain; charset=urf-8') {
                            resolve(
                                    // 对响应结果二次包装
                                    Object.assign(
                                      {
                                           success: Number(response.data.code) === 200,
                                            data: response.data.data,
                                            msg: response.data.msg
                                        },
                                       response.data
                                    )
                                ) // 处理返回结果
                            } else {
                                resolve(response.data)
                            }
                        }
                    }, response => {
                        // 处理错误码
                      if(response.response) {
                            const statusCode = response.response.status
                            this.handleErrorStatus(statusCode)
                        } else {
                           Vue.prototype.$message.error(response.message)
                        }
                        reject(response)
                    })
                    .catch(err => {
                        reject(err)
                    })
                })
            }
        }
    }
​
    // 请求成功,返回错误码
    // 具体状态码跟后台开发人员统一,然后根据状态码进行相应提示
    // 下面是我在项目中的操作,大家可自行调整扩展
    handleSuccessStatus (code, data) {
        let result = ''
        let flag = false
        switch (code) {
            case '20007':
                result = '未查找到二次认证密码!'
                flag = true
                break
            case '20008':
                result = '您的二次认证密码还未修改,请先修改!'
                flag = true
                break
            case '20009':
                result = '您还未开启二次认证,请联系管理员!'
                flag = true
                break
            case '90001':
                result = '请输入二次认证密码!'
                flag = true
                break
            case '90002':
                result = '无操作权限!'
                flag = true
                break
            default:
                break
        }
​
        // 进行通知
        // $message方法是我按需引入的element-ui中的提示组件,你可以替换成自己的提示组件
        if (result) {
            Vue.prototype.$message.error(result)
        }
        return flag
    }
    // 根据错误码获取错误提示
    handleErrorStatus (statusCode) {
        let errorMsg = ''
        if (statusCode === 500) {
            errorMsg = '数据请求失败,请联系管理员!'
        } else if (statusCode === 404) {
            errorMsg = '请求地址错误!'
        } else if (statusCode === 402) {
            errorMsg = '当前您没有权限操作该数据!'
        } else {
            errorMsg = '请求出错!'
        }
        // 进行通知
        Vue.prototype.$message.error(errorMsg)
    }
}
​
export default new Request() 

6、使用

我们在接口管理文件中,通过调用上面封装的 request 类,传入对应的参数即可。

user.api.js 文件:

import http from '../services/request'
​
/**
 * @description 获取用户列表
 * @param {*} params 请求接口的参数
 */
// 此处定义的reqUserList方法会调用我们封装的request中的get方法,get方法的第一个参数是请求地址,第二参数是query参数
export const reqUserList = params => http.get('/user/list', params) 

在调用的 .vue 文件中,引入该方法并传入参数即可

import { reqUserList } from '@Apis/user.api' // 导入api
​
export default {
    name: 'UserList',
    ... ...
    created() {

    },
    methods: {
        async getUsers() {
            // 调用api接口,并传入参数
            const res = await reqUserList({
                page: 1,
                size: 10
            })
            console.log(res) // 获取的响应结果
        }
    }
}

如此,就完成了对接口的封装及基本使用。

PS:以上这些文件名、文件夹名、方法名、路径等都是我自己取得,你可以按照自己的代码风格习惯进行调整。

以上就是如何在Vue项目中使用axios请求的详细内容,更多关于Vue项目中使用axios的资料请关注我们其它相关文章!

(0)

相关推荐

  • vue中axios封装使用的完整教程

    前言 如今,在项目中,普遍采用Axios库进行Http接口请求.它是基于promise的http库,可运行在浏览器端和node.js中.此外还有拦截请求和响应.转换JSON数据.客户端防御XSRF等优秀的特性. 考虑到各个项目实际使用时写法混乱,不统一.对Axios进行一下通用化的封装,目的是帮助简化代码和利于后期的更新维护,尽量通用化. 方法如下 1. vue安装axios npm install axios -S 或者 npm i axios -S 2. 在main.js进行全局引入 imp

  • Vue项目利用axios请求接口下载excel

    本文实例为大家分享了Vue项目利用axios请求接口下载excel的具体代码,供大家参考,具体内容如下 据我了解的前端的下载方式有三种,第一种是通过a标签来进行下载,第二种时候通过window.location来下载,第三种是通过请求后台的接口来下载,今天就来记录一下这三种下载方式. 方法一:通过a标签 // href为文件的存储路径或者地址,download为问文件名 <a href="/images/logo.jpg" rel="external nofollow&

  • Vue项目中如何封装axios(统一管理http请求)

    1.需求说明 在使用Vue.js框架开发前端项目时,会经常发送ajax请求服务端接口,在开发过程中,需要对axios进一步封装,方便在项目中的使用. 2.Vue项目结构 在本地创建Vue项目,目录结构如下: - public  静态资源文件  - src  |- assets  静态资源目录  |- components 公共组件目录  |- http   axios封装目录  |- router  路由管理目录  |- store  状态管理目录  |- views  视图组件目录  |- A

  • vue-axios同时请求多个接口 等所有接口全部加载完成再处理操作

    我就废话不多说了,大家还是直接看代码吧~ Axios.all([request1, request2, request3]) .then( Axios.spread((area, acct, perms) => { console.log('全部加载完成') }) ) .catch(err => { console.log(err.response) }); 需要在当前路由引入axios import Axios from "axios"; 补充知识:vue,axios处理

  • 解决vue 使用axios.all()方法发起多个请求控制台报错的问题

    今天在项目中使用axios时发现axios.all() 方法可以执行但是控制台报错,后来在论坛中看到是由于axios.all() 方法并没有挂载到 axios对象上,需要我们手动去添加 == 只需要在你封装的axios文件里加入 == instance.all = axios.all 就完美解决了! 补充知识:vue项目中使用axios.all处理并发请求报_util2.default.axios.all is not a function异常 报错: _util2.default.axios.

  • Vue3配置axios跨域实现过程解析

    实现跨域共3个步骤: 1,vue3.0根目录下创建vue.config.js文件: module.exports = { devServer: { proxy: { '/api': { target: 'https://you.163.com/', //接口域名 changeOrigin: true, //是否跨域 ws: true, //是否代理 websockets secure: true, //是否https接口 pathRewrite: { //路径重置 '^/api': '' } }

  • 基于axios请求封装的vue应用实例代码

    什么是axios? Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. 特性: 从浏览器中创建 XMLHttpRequests 从 node.js 创建 http 请求 支持 Promise API 拦截请求和响应 转换请求数据和响应数据 取消请求 自动转换 JSON 数据 客户端支持防御 XSRF Promises axios 依赖原生的 ES6 Promise 实现而被支持. 如果你的环境不支持 ES6 Promise,你可以使用 polyfil

  • vue中封装axios并实现api接口的统一管理

    在vue项目中,我们通常都是使用axios与后台进行数据交互,axios有很多好用的特性,这里不多做介绍,相关细节可以查阅axios中文网.在对axios进行封装之前,我们要使用vue脚手架工具创建一个vue项目(这里我用的是cli4). 安装 cnpm install axios --save-dev; // 安装axios cnpm install qs --save-dev; // 安装qs模块,用来序列化post类型的数据,否则后端无法接收到数据 模块引入 在src目录下创建一个serv

  • Vue3+TypeScript封装axios并进行请求调用的实现

    不是吧,不是吧,原来真的有人都2021年了,连TypeScript都没听说过吧?在项目中使用TypeScript虽然短期内会增加一些开发成本,但是对于其需要长期维护的项目,TypeScript能够减少其维护成本,使用TypeScript增加了代码的可读性和可维护性,且拥有较为活跃的社区,当居为大前端的趋势所在,那就开始淦起来吧~ 使用TypeScript封装基础axios库 代码如下: // http.ts import axios, { AxiosRequestConfig, AxiosRes

  • vue 导航守卫和axios拦截器有哪些区别

    在Vue项目中,有两种用户登录状态判断并处理的情况,分别为:导航守卫和axios拦截器. 一.什么是导航守卫? vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航.(在路由跳转时触发) 我们主要介绍的是可以验证用户登录状态的全局前置守卫,当一个导航触发时,全局前置守卫按照创建顺序调用.守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中. const router = new VueRouter({ ... })   router.beforeEac

随机推荐