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>

posted @ 2025-05-12 17:05  莫晓゜  阅读(41)  评论(0)    收藏  举报