在理论的我的项目中,和后盾的数据交互是少不了的,我通常应用的是 axios 库,所以以下示例也是以 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(err)})

这样写也不是不能够,但存在一些缺点,接口申请的 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 切换不同的 baseURLconst 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' // 导入apiexport default {    name: 'UserList',    ... ...    created() {},    methods: {        async getUsers() {            // 调用api接口,并传入参数            const res = await reqUserList({                page: 1,                size: 10            })            console.log(res) // 获取的响应后果        }    }}

如此,就实现了对接口的封装及根本应用。

PS:以上这些文件名、文件夹名、办法名、门路等都是我本人获得,你能够依照本人的代码格调习惯进行调整。

以上,是我在我的项目中的一些写法,有的中央可能不欠缺,如有问题欢送大家斧正,感激 :)