细谈Axios中那些不为人知的秘密!一文读懂Axios(四)

简介: 细谈Axios中那些不为人知的秘密!一文读懂Axios

axios请求的封装与使用

思路分析

axios 请求的封装,无非是为了方便代码管理,我们可以使用抽离拆分的思想,将不同功能模块的接口处理成不同的模块,然后封装一个方法,专门用于数据交互。

第一步:新建 src/service/contactApi.js 文件

const CONTACT_API = { 
    // 获取联系人列表
    getContactList:{ 
        method:'get',
        url:'/contactList'
    },
    // 新建联系人 form-data
    newContactForm:{ 
        method:'post',
        url:'/contact/new/form'
    },
    // 新建联系人 application/json
    newContactJson:{ 
        method:'post',
        url:'/contact/new/json'
    },
    // 编辑联系人
    editContact:{ 
        method:'put',
        url:'/contact/edit'
    },
    // 删除联系人
    delContact:{ 
        method:'delete',
        url:'/contact'
    }
}
export default CONTACT_API

备注:该文件的用途只有一个,定义不同的接口请求信息(包含 method、***url***等)并导出使用。当接口增加或者删除的时候,只需要定义在该文件中即可。

第二步:新建 src/service/http.js 文件

import axios from 'axios'
import service from './contactApi'
import {  Toast } from 'vant'
// service 循环遍历输出不同的请求方法
let instance = axios.create({ 
    baseURL: 'http://localhost:9000/api',
    timeout: 1000
})
const Http = { }; // 包裹请求方法的容器
// 请求格式/参数的统一
for (let key in service) { 
    let api = service[key]; // url method
    // async 作用:避免进入回调地狱
    Http[key] = async function(
        params, // 请求参数 get:url,put,post,patch(data),delete:url
        isFormData = false, // 标识是否是form-data请求
        config = { } // 配置参数
    ) { 
        let newParams = { }
        // content-type是否是form-data的判断
        if (params && isFormData) { 
            newParams = new FormData()
            for (let i in params) { 
                newParams.append(i, params[i])
            }
        } else { 
            newParams = params
        }
        // 不同请求的判断
        let response = { }; // 请求的返回值
        if (api.method === 'put' || api.method === 'post' || api.method === 'patch') { 
            try { 
                response = await instance[api.method](api.url, newParams, config)
            } catch (err) { 
                response = err
            }
        } else if (api.method === 'delete' || api.method === 'get') { 
            config.params = newParams
            try { 
                response = await instance[api.method](api.url, config)
            } catch (err) { 
                response = err
            }
        }
        return response; // 返回响应值
    }
}
// 拦截器的添加
// 请求拦截器
instance.interceptors.request.use(config => { 
        // 发起请求前做些什么
        Toast.loading({ 
            mask: false,
            duration: 0, // 一直存在
            forbidClick: true, // 禁止点击
            message: '加载中...'
        })
        return config
    }, () => { 
        // 请求错误
        Toast.clear()
        Toast('请求错误,请求稍后重试')
    })
    // 响应拦截器
instance.interceptors.response.use(res => { 
    // 请求成功
    Toast.clear()
    return res.data
}, () => { 
    Toast.clear()
    Toast('请求错误,请求稍后重试')
})
export default Http

具体的思路步骤如下:

首先,我们引入contactApi.js文件,别名定义为 service

import service from './contactApi'

定义 http 作为请求方法的容器,配置对应的参数(即请求方法中的其他信息,比如 headers,content-type,token等等)。需要注意的是,在其中我们要区分 content-type的形式有两种:form-data 与 application/json,它们的参数配置不同,form-data 形式的参数,我们需要定义 Formdata 对象。具体如下:

let newParams = { }
// content-type是否是form-data的判断
if (params && isFormData) { 
    newParams = new FormData()
    for (let i in params) { 
        newParams.append(i, params[i])
    }
} else { 
    newParams = params
}

温馨提示:其中 isFormData 定义为 Boolean 变量,用于标识是否为 FormData 形式。

根据不同的请求方式,发起网络请求,并导出返回值。

// 不同请求的判断
let response = { }; // 请求的返回值
if (api.method === 'put' || api.method === 'post' || api.method === 'patch') { 
    try { 
        response = await instance[api.method](api.url, newParams, config)
    } catch (err) { 
        response = err
    }
} else if (api.method === 'delete' || api.method === 'get') { 
    config.params = newParams
    try { 
        response = await instance[api.method](api.url, config)
    } catch (err) { 
        response = err
    }
}
return response; // 返回响应值

注意:对于不同方法的区别在于:getdelete 的参数在 config 中配置,而不是使用 params

设置请求拦截器与响应拦截器

/ 拦截器的添加
// 请求拦截器
instance.interceptors.request.use(config => { 
        // 发起请求前做些什么
        Toast.loading({ 
            mask: false,
            duration: 0, // 一直存在
            forbidClick: true, // 禁止点击
            message: '加载中...'
        })
        return config
    }, () => { 
        // 请求错误
        Toast.clear()
        Toast('请求错误,请求稍后重试')
    })
    // 响应拦截器
instance.interceptors.response.use(res => { 
    // 请求成功
    Toast.clear()
    return res.data
}, () => { 
    Toast.clear()
    Toast('请求错误,请求稍后重试')
})

导出src/service/http.js文件,用于其他地方的引入。

export default Http

第三步:在入口文件中导入 http.js ,并挂载到 vue 原型上。

1. import Http from './service/http'
2. // 把Http挂载到Vue实例上
3. Vue.prototype.$Http = Http

第四步:在组件中使用封装的请求

// 获取联系人列表
async getList(){ 
    let res = await this.$Http.getContactList()
    this.list = res.data
},

注意:在使用的时候,我们需要结合 async 与 await 才能正确使用。具体的使用方法是:


在定义的网络请求函数前增加 async 标识。

在接收请求返回数据的时候,增加 await 标识。

提示:在上面函数中,只有在 res 拿到后才会执行 this.list = res.data; 相当于在对应的 then 中执行的语句,避免了回调地狱。

axios在提交表单请求时会自动设置content-type,此时手动设置时无效的。

总结

在进行项目开发的时候,我们需要对网络请求的方法进行封装,可以有效地减少后期代码维护的难度,建议开发者根据不同的功能模块进行拆分,方便后期代码问题的定位。另外,也能实现代码的低耦合,避免出现更多的重复代码。

相关文章
细谈Axios中那些不为人知的秘密!一文读懂Axios(二)
细谈Axios中那些不为人知的秘密!一文读懂Axios
171 0
|
2月前
|
资源调度 JavaScript
|
4月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
2月前
|
缓存 JavaScript 搜索推荐
|
4月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
3月前
|
JavaScript 前端开发 开发者
vue中使用axios请求post接口,请求会发送两次
vue中使用axios请求post接口,请求会发送两次
|
2月前
|
前端开发 JavaScript 安全
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
141 4
|
3月前
|
JavaScript
vue 中 axios 的安装及使用
本文介绍了在Vue项目中安装和使用axios的方法。首先通过命令`npm install axios --save-dev`安装axios,然后在组件的`created`生命周期钩子中使用`axios.get`异步获取数据,并将获取的数据更新到组件的`data`中。文中提供了完整的示例代码,包括安装命令、验证安装成功的步骤、Vue组件的模板、脚本和样式。
vue 中 axios 的安装及使用
|
3月前
|
JSON 资源调度 JavaScript
Vue框架中Ajax请求的实现方式:使用axios库或fetch API
选择 `axios`还是 `fetch`取决于项目需求和个人偏好。`axios`提供了更丰富的API和更灵活的错误处理方式,适用于需要复杂请求配置的场景。而 `fetch`作为现代浏览器的原生API,使用起来更为简洁,但在旧浏览器兼容性和某些高级特性上可能略显不足。无论选择哪种方式,它们都能有效地在Vue应用中实现Ajax请求的功能。
46 4