uni-app封装usePageList加载页面列表hooks

1,692 阅读1分钟

场景

uni-app 加载页面列表

1683704976428.jpg 如上图,如果不使用hooks,将重复写相同逻辑的代码 使用之后,代码量大大节省

1683705236633.png

hooks代码

// usePageList.ts
import { ref, type Ref } from 'vue'

interface ListOptionsRes<T> {
  content: T[]
  first: boolean
  last: true
  size: boolean
  totalElements: number
  totalPages: number
}

interface ListServiceParams {
  page: number
  size: number
}

type ListService<R> = (params: ListServiceParams) => Promise<ResOptions<ListOptionsRes<R>>>

interface Options {
  page?: number
  size?: number
}

type Status = 'more' | 'loading' | 'nomore'

export function usePageList<T>(service: ListService<T>, options: Options = {}) {
  const page = ref(options.page ?? 1)
  const size = ref(options.size ?? 10)
  const loading = ref(false)
  const status = ref<Status>('more')
  const total = ref(0)

  const list: Ref<T[]> = ref([])
  const getList = async () => {
    try {
      status.value = 'loading'
      const res = await service({ page: page.value, size: size.value })
      if (list.value.length < res.data.totalElements) {
        list.value.push(...res.data.content)
      }
      status.value = list.value.length >= res.data.totalElements ? 'nomore' : 'more'
      page.value = list.value.length >= res.data.totalElements ? page.value : page.value + 1
    } catch (error) {
      status.value = 'more'
    }
  }

  const search = () => {
    list.value = []
    page.value = options.page ?? 1
    getList()
  }

  return {
    page,
    size,
    loading,
    status,
    total,
    list,
    getList,
    search
  }
}

使用

<template>
  <view class="page">
    <view class="list">
      <provider-item v-for="item in providerList" :key="item.id" :data="item"></provider-item>
      <load-more :status="status"></load-more>
    </view>
  </view>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { getWindProviderList, type WindProviderItem } from '@/apis'
import { onReachBottom } from '@dcloudio/uni-app'
import { usePageList } from '@/hooks'

const form = reactive({ industry: '', area: [] as string[], company: '' })

const {
  list: providerList,
  status,
  getList
} = usePageList<WindProviderItem>((params) => getWindProviderList({ ...params, ...form }))

getList()

// 下拉加载触发
onReachBottom(() => {
  getList()
})
</script>