更新记录
1.0.1(2021-10-26)
下载此版本
优化了下,添加了更多状态。
1.0.0(2021-09-03)
下载此版本
无
平台兼容性
App |
快应用 |
微信小程序 |
支付宝小程序 |
百度小程序 |
字节小程序 |
QQ小程序 |
app-vue app-nvue |
√ |
√ |
√ |
√ |
√ |
√ |
钉钉小程序 |
快手小程序 |
飞书小程序 |
京东小程序 |
× |
× |
× |
× |
H5-Safari |
Android Browser |
微信浏览器(Android) |
QQ浏览器(Android) |
Chrome |
IE |
Edge |
Firefox |
PC-Safari |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
示例
代码
/**
* 描述:异步状态管理
* 参数1 apiFunc
* 必须是一个Promise。
* 参数2 option
* manual:是否要手动出发,默认false,初始化时候就会调用一次接口,否则则需要自己手动调用run方法
* onSuccess:成功时候的回调,返回获取的数据
* onError:失败时候的回调,返回失败信息
* loadMoreMod 将以 加载更多 模式运行 将所有请求数据合并数组 .then(e)成功返回的数据必须有为{total:Number,records:[]},不是的自己await时候洗一下.
* 返回值
* 普通模式下
* let state = {
data: null, //返回的数据
loading: !manual, //是否正在加载
error: null, //错误信息
isRefresh: false, //是否正在局部刷新
run(params) ,调用接口,params是参数,会直接传给了apiFunc(params),当然如果你的apifunc不接受参数,那就当然没用了。
reFresh() 局部刷新。和run的区别就是,调用的时候不会将data重新置为null,而是在加载成功后替换掉。
}
加载更多模式下
let state = {
data: null, //返回的数据
loading: !manual, //是否正在加载
error: null, //错误信息
run(params) ,调用接口,params是参数,会直接传给了apiFunc(params),当然如果你传递apiFunc不接受参数,那就当然没用了。
isThereMore:是否还有更多的数据
loadingMore:是否正在加载更多中
isReloading:是否正在重新加载中,只是为了和loading状态区分开。
reLoad():重新加载
loadMore():加载更多
}
*/
function useRequest(apiFunc, option = {
manual: false,
onSuccess: false,
onError: false,
loadMoreMod:false,
}) {
const {manual, onSuccess, onError,loadMoreMod} = option
//通用状态
let state = {
data: null,
loading: !manual,
error: null,
isRefresh: false,
}
//如果开启了加载更多模式则添加【是否有更多数据状态】
if(loadMoreMod){
state.isThereMore=true
state.loadingMore=false
state.isReloading=false
}
//保存下查询的参数,列表带参数,调用reload后传递的参数保存下,给下次loadMore时候用。
let tempParams=""
const execute = (params,opt={isRefresh:false,isReload:false}) => {
const {isRefresh,isReload}=opt
apiFunc(params)
.then((e) => {
state.loading = false
//加载更多模式 合并请求的数据
if(loadMoreMod){
state.loadingMore=false
handleLoadMoreModData(e,isReload)
}
//普通模式
else {
state.data = e
if(isRefresh){
state.isRefresh=false
}
}
//如果是正在reload 关闭状态
if(isReload)
state.isReloading=false
if (onSuccess) {
onSuccess(e)
}
})
.catch((e) => {
state.error = e.toString()
state.loading = false
if(isRefresh){
state.isRefresh=false
}
uni.showToast({
title: '错误:' + e.toString(),
icon: "none",
duration: 2000
})
if (onError) {
onError(e.toString())
}
})
}
//加载更多模式下处理s tate.data 合并数据
const handleLoadMoreModData=(e,isReload)=>{
const {total,records}=e
//第二次之合并数据 如果不是reload
if(state.data&&!isReload){
//合并数据
state.data=[...state.data,...records]
//判断是否还有数据
const recordsLength=state.data.length
/*
* 为啥是大于等于呢,正常情况下等于是没问题的
* 但是第一次查10条,一共十二条,第二次查询的时候,突然删的只剩下一条数据了,那么返回的total是不是1 是不是就比当前合并的数组少了。
* */
if(recordsLength>=total)
state.isThereMore=false
}
//第一次直接赋值
else{
//如果有值
if(total!==0)
state.data=records
else{
state.data=[]
state.isThereMore=false
}
}
}
//普通执行 会清空之前查询的数据 相当于reLoad 、
const run = (params) => {
if(loadMoreMod){
state.loadingMore=false
state.isThereMore=true
state.isReloading=false
tempParams=params//加载更多模式保存查询参数,给reload,和loadMore用
}
state.error = null//重置错误状态
state.loading = true//加载状态改为加载中
state.data = null//重置之前查询的数据
//执行
execute(params)
}
//局部刷新
const reFresh=()=>{
state.isRefresh = true//加载状态改为加载中
//执行
if(tempParams)
execute(tempParams,{isRefresh: true})
else
execute(undefined,{isRefresh: true})
}
//加载更多
const loadMore=()=>{
//如果还要更多的数据,而且当前不是正在加载更多的状态
if(state.isThereMore&&!state.loadingMore){
state.loadingMore=true
//执行
//如果有保存的参数,则传递保存的参数
if(tempParams)
execute(tempParams)
else
execute()
}
}
//重新加载
const reload=()=>{
state.loading=false
state.error=null
state.loadingMore=false
state.isThereMore=true
state.isReloading=true
//执行
if(tempParams)
execute(tempParams,{isReload:true})
else
execute(undefined,{isReload:true})
}
//如果手动触发为false,则直接run查询
if (!manual) run()
state.run=run
//加载更多模式不适用局部刷新
if(!loadMoreMod){
state.reFresh=reFresh
}
//只有加载更多模式下才有的reload 和loadMore
if(loadMoreMod){
state.reload=reload
state.loadMore=loadMore
}
return state
}
export {
useRequest
}