一、封装步骤
1. 在项目的根目录创建目录结构如下:
封装的请求方法代码如下:
// 全局请求路径,也就是后端的请求基准路径
const BASE_URL = 'http://192.168.31.39:8899/'
// 同时发送异步代码的次数,防止一次点击中有多次请求,用于处理
let ajaxTimes=0;
// 封装请求方法,并向外暴露该方法
export const myHttp = (options)=>{
// 解构请求头参数
let header = {...options.header};
// 当前请求不是登录时请求,在header中加上后端返回的token
if(options.url != 'login'){
header["client-identity"] = uni.getStorageSync('session_id');
}
ajaxTimes++;
// 显示加载中 效果
uni.showLoading({
title: "加载中",
mask: true,
});
return new Promise((resolve,reject)=>{
uni.request({
url:BASE_URL+options.url,
method: options.method || 'POST',
data: options.data || {},
header,
success: (res)=>{
resolve(res)
},
fail: (err)=>{
reject(err)
},
// 完成之后关闭加载效果
complete:()=>{
ajaxTimes--;
if(ajaxTimes===0){
// 关闭正在等待的图标
uni.hideLoading();
}
}
})
})
}
2.为了利于方法的复用,在main.js中做引入,并且挂载到vue的原型对象身上,这样就可以在项目的任意单文件中使用:
import { myHttp } from './util/api.js'
Vue.prototype.$myHttp = myHttp
3.方法的具体使用(此处省略表单校验以及登录成功之后的业务逻辑):
async login(){
// 发送请求
const {data:res} = await this.$myHttp({
url: 'login',
data:{
name:this.username.trim(),
password:this.$md5(this.password.trim())
}
});
if(res.code != 200) return uni.showToast({
title:'用户名或密码不正确',
duration: 1500,
icon:'none'
});
// 将session_id保存到缓存中
uni.setStorageSync('session_id',res.data.session_id)
// 登录成功跳转到首页
uni.switchTab({
url: '/pages/index/index'
})
}
二、封装思路解析
-
1.请求期间的Loading解析
在请求发送前利用uniapp原生的api:uni.showLoading
打开Loading样式,在请求完成时再利用uni.hideLoading
关闭Loading样式。关闭loading样式的代码放在complete函数中是因为,无论请求成功还是失败,只要请求结束,都要关闭loading样式。
-
2.ajaxTimes变量的解析
通常会遇到请求被同时发送的情况,例如在点击按钮之后,在事件处理函数中向后端发送了两次或者以上次数的请求
,那么不能在第一次请求结束就关闭了Loading。所以添加了ajaxTimes变量进行控制,每次请求发起时都将变量做++操作,请求结束一次做- -操作,这样当所有请求都结束时ajaxTimes的值又变成了初始定义的0,那么就可以进行Loading的关闭操作。
-
3.请求前是否添加后端需要的请求头验证(在请求头携带token或sessionId,名字不一样而已,不必在意)
在用户进行登录请求时,是不需要添加请求头验证的,但是登录之后,每次请求都需要进行身份验证,所以在请求方法中添加了当前操作是否是登录操作:
if(options.url != 'login'){
header["client-identity"] = uni.getStorageSync('session_id');
}
不是登录操作则将保存在缓存中的身份验证下带在请求头中。