为什么要对axios进行封装?
- 实际开发过程中,我们项目可能会有大量接口,因此我们写代码的时候,如果不进行封装,则会产生大量冗余代码,比如
catch
,还有就是大量的接口也会造成后期维护的麻烦
封装通常包含几个部分
- API的封装,便于后期统一维护管理。
不同类型的接口,分门别类放入不同的文件进行管理,然后把这些文件放入统一的文件夹里。例如,联系人这个类型的接口,我们就可以单独放入一个文件,姑且命名为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
- 对axios进行封装
import axios from 'axios'
import service from './contactApi'
import { Toast } from 'vant'
let instance = axios.create({
baseURL:'http://localhost:9000/api',
timeout:1000
})
const Http = {}; //包裹请求方法的容器
// 对 service 进行循环遍历输出不同的请求方法,也就是遍历 CONTACT_API
// 下边会将 请求格式/参数 进行统一为 params,isFormData,config
for(let key in service){
let api = service[key] //api包含url method
Http[key] = async function(
//方法接受的参数
//参数1 --- 请求参数params
// get请求的话,参数放到URL上
// post、put、patch请求的话,对应的参数是data
// delete请求的话,默认放在URL上(当然也可以放在data)
params,
//参数2 --- isFormData 标识是否是 form-data 请求,默认不是
isFormData = false,
//参数3 --- config 配置参数,可以在这里设置 headers、params、data等
config = {}
){
//声明新变量,判断content-type是否是form-data时候的参数的转换
let newParams = {}
// 判断 content-type 是否是 form-data
if(params && isFormData){
newParams = new FormData() //创建一个form-data格式的对象
for(let i in params){
newParams.append(i,params[i])
}
}else{
//不是form-data
newParams = params
}
// 不同请求的判断
let response = {}; //请求的返回值
if (api.method === 'post' || api.method === 'put' || api.method === 'patch'){
try{
response = await instance[api.method](api.url, newParams,config)
}catch(err){
response = err
}
} else if (api.method === 'get' || api.method === 'delete'){
config.params = newParams
try {
response = await instance[api.method](api.url, config)
} catch (err) {
response = err
}
}
return response //返回响应值
}
}
//请求拦截器
instance.interceptors.request.use(
config => {
//发起请求前做什么
//加一个动态更新提示
Toast({
duration: 0, // 持续展示 toast
forbidClick: true, //是否禁止背景点击
message: '加载中...'
})
return config
},
() => {
//请求错误
Toast.clear() //因为Toast是一直展示的,所以请求错误时需要关掉toast
Toast('请求错误,请稍后重试')
}
)
//响应拦截器
instance.interceptors.response.use(
//响应成功
res => {
Toast.clear()
return res.data
},
() => {
Toast.clear()
Toast('请求错误,请稍后重试')
}
)
export default Http
- 挂载到Vue原型上(main.js里操作),之所以要挂载,是为了不在每个页面都进行
import axios from 'axios'
这样类似的操作了,挂载之后,全局可用。
image.png
- 改造联系人代码
<template>
<div class="home">
<!-- 联系人列表 -->
<van-contact-list
:list="list"
@add="onAdd"
@edit="onEdit"
/>
<!-- 联系人编辑-->
<van-popup v-model="showEdit" position="bottom">
<van-contact-edit
:contact-info="editingContact"
:is-edit="isEdit"
@save="onSave"
@delete="onDelete"
/>
</van-popup>
</div>
</template>
<script>
import axios from 'axios'
import { ContactList,ContactEdit,Toast,Popup} from 'vant';
export default {
name: 'ContactList',
components:{
[ContactList.name]:ContactList,
[ContactEdit.name]:ContactEdit,
[Popup.name]:Popup
},
data(){
return {
// {
// id:'',
// name:'',
// tel:''
// }
list:[],
instance:null, //axios实例
showEdit:false, //编辑弹窗的显隐
editingContact:{}, //正在编辑的联系人数据
isEdit:false, //新建或编辑
}
},
created(){
this.instance = axios.create({
baseURL:'http://localhost:9000/api',
timeout:1000
})
this.getContactList()
},
methods:{
//获取联系人列表(改造后)
async getContactList(){
let res = await this.$Http.getContactList()
this.list = res.data
},
//添加联系人
onAdd(){
this.showEdit = true
this.isEdit = false
},
//编辑联系人
onEdit(info){
this.showEdit = true
this.isEdit = true
this.editingContact = info
},
//保存联系人
async onSave(info){
if(this.isEdit){
//编辑保存
let res = await this.$Http.editContact(info)
if(res.code == 200){
Toast('编辑成功')
this.showEdit = false
this.getContactList()
}
}else{
//新建保存
//传的3个参数,第二个应该传false,因为默认是false,所以可以不写,config也不需要传
let res = await this.$Http.newContactJson(info)
if(res.code == 200){
Toast('新建成功')
this.showEdit = false
this.getContactList()
}
//form-data格式
// let res = await this.$Http.newContactForm(info,true)
// if(res.code == 200){
// Toast('新建成功')
// this.showEdit = false
// this.getContactList()
// }
}
},
//删除联系人人
async onDelete(info){
let res = await this.$Http.delContact({
id:info.id
})
if(res.code == 200){
Toast('删除成功')
this.showEdit = false
this.getContactList()
}
}
}
}
</script>
<style scoped>
.van-popup {
height:40%
}
</style>
网友评论