uniapp(h5)列表自动分页 无需total 自定义hooks
如果要复制到自己项目要适当修改useRequest实现
import { httpGet, httpPost } from '@/utils/http'
import { useGlobalStore } from '@/store'
import { t } from '@/locale'
import { ref, computed } from 'vue'
import useRequest from '@/hooks/useRequest'
export const useTableList = (
// apiUrl: string,
params: Record<string, any> = {
// 默认使用 httpGet 方法
httpPromise: httpGet,
formatList: (data) => data.data,
},
) => {
// INFO: 分页逻辑
const page = ref(1)
const pageSize = ref(10)
const {
list: dataList,
run: getList,
data: listData,
} = useRequest(
() => {
return params.httpPromise({
page: page.value,
pageSize: pageSize.value,
})
},
{
immediate: false,
formatList: params.formatList,
},
)
// 计算当前页数总条目数
type StateType = 'loading' | 'finished' | 'error'
const bottomMoreState = ref<StateType>('loading')
const fullPageList = ref<LotteryLogItem[]>([])
const getListFunc = () => {
return new Promise<void>((resolve, reject) => {
getList()
.then(() => {
if (!dataList.value?.length || dataList.value?.length < pageSize.value) {
bottomMoreState.value = 'finished'
} else {
page.value++
bottomMoreState.value = 'loading'
}
// 将数据添加到 fullPageList 中
fullPageList.value = [...fullPageList.value, ...dataList.value]
resolve()
})
.catch((error) => {
bottomMoreState.value = 'error'
console.log(error)
reject(new Error(error))
})
})
}
// TODO: loading 状态
const isLoading = ref(false) // loading 状态
const isFinished = ref(false) // finished 状态
const run = async () => {
useGlobalStore().showToast('loading', t('toast.loading'))
isLoading.value = true // 开始加载
try {
await getListFunc()
isFinished.value = bottomMoreState.value === 'finished' // 根据 bottomMoreState 更新 finished 状态
} catch (error) {
console.error(error)
} finally {
isLoading.value = false // 加载结束
useGlobalStore().hideLoading()
}
}
const state = computed(() => {
return {
loading: isLoading.value,
finished: isFinished.value,
bottomMoreState: bottomMoreState.value,
}
})
const refreshList = async (cb?: () => void): Promise<void> => {
page.value = 1
fullPageList.value = []
await run()
cb && cb() // 确保 cb 存在再调用
}
return {
list: fullPageList,
tableData: listData,
run,
state,
refreshList,
}
}
在使用的地方:
<route lang="json5">
{
style: {
navigationBarTitleText: '%copy.addHistory%',
navigationStyle: 'custom',
},
}
</route>
<template>
<custom-nav-bar :title="$t('copy.addHistory')" />
<view class="pb-10">
<!-- <CopyHistoryCard v-for="item in followAddHistory" :key="item.appendOrderNo" :item="item" /> -->
<CopyHistoryCard
v-for="item in list"
:key="item.appendOrderNo"
:item="item"
:systemConfig="systemConfig"
/>
<!-- <data-empty v-if="followAddHistory.length === 0" /> -->
<data-empty v-if="!state.loading && state.finished && !list.length" />
<wd-loadmore
v-if="list.length"
class="text-20rpx"
:state="state.bottomMoreState"
@reload="tableLoad"
:loading-text="$t('loading')"
:finished-text="$t('noMore')"
:error-text="$t('loadFailed')"
/>
</view>
</template>
<script setup lang="ts">
import DataEmpty from '@/components/DataEmpty.vue'
import CopyHistoryCard from './CopyHistoryCard.vue'
import { useFollowStore } from '@/store/follow'
import { useTableList } from '@/hooks/useTableList'
import { httpGet } from '@/utils/http'
import { onLoad } from '@dcloudio/uni-app'
import { useAuthStore } from '@/store'
const { fetchMyFollowAddHistory, followInfo, parseUrlFollowOrderId } = useFollowStore()
// const {
// list,
// run: tableLoad,
// state,
// } = useTableList(/api/user/append/orders/my/${parseUrlFollowOrderId()})
const { authInfo, fetchSystemConfig } = useAuthStore()
const systemConfig = computed(() => {
return authInfo.systemConfig
})
const {
list,
run: tableLoad,
state,
} = useTableList({
formatList: (data) => data.data,
httpPromise: (params) => {
return httpGet(/api/user/append/orders/my/${parseUrlFollowOrderId()}, {
...params,
})
},
})
onLoad(() => {
// fetchMyFollowAddHistory()
tableLoad()
fetchSystemConfig()
})
onReachBottom(() => {
if (state.value.bottomMoreState !== 'finished') {
tableLoad()
}
})
</script>