1.html 

<template>
  <div>
    <!-- 显示列表数据 -->
    <slot v-if='list' :list="list"></slot>
    <!-- 加载更多组件 上拉加载 -->
    <fui-loadmore v-if="_loading"></fui-loadmore>
    <!-- 分割线 -->
    <fui-divider :size="size+'rpx'" dividerColor="#465CFF" color="#465CFF" :text="text" v-if="finished"></fui-divider>
  </div>
</template>

2.js 


<script lang="ts" setup>
  import { toast } from '@/utils/uniTools';

  interface IProp {
    //用于执行异步请求并返回一个promise对象,其中Promise对象的解析值是一个表示请求结果的自定义类型result 
    request : (params ?: any) => Promise<Result<any>>
    params ?: Record<string, any>
    refresh ?: boolean
    loadmore ?: boolean
    skeletonLength ?: number
    //经纬度 
    longitude_latitude ?: string
    text ?: string
    //运营商id 
    proxy_id ?: number
    //分割线字体大小
    size ?: number
  }
  const props = withDefaults(defineProps<IProp>(), {
    params: () => ({}),
    //允许刷新数据列表
    refresh: true,
    //是否允许上拉加载更多数据
    loadmore: true,
    //骨架屏的元素数量
    skeletonLength: 3,
    text: '没有更多了',
    size: 24
  })

  const list = ref<any[]>([])
  const page = ref(1)
  const total = ref(0)
  const pagesize = ref(10)
  const loading = ref(false)
  const finished = ref(false)

  const setPage = (newPage : number) => {
    page.value = newPage
  }
  const setSize = (newPage : number) => {
    pagesize.value = newPage
  }
  const _loading = computed(() => {
    //当loading值为真,且finished的值为假的时候,_loaing为true
    return loading.value && !finished.value
  })

  //监听params的变化,当参数变化时重新调用
  watch(() => [props.params, props.longitude_latitude], () => {
    finished.value = false
    list.value = []
    page.value = 1
    getList()
  }, {
    deep: true
  })
  //获取数据
  const getList = async () => {
    if (loading.value) return
    loading.value = true
    console.log('传过来的参数', props.params)
    // aaa.value = '获取到传过来的参数,开始调用接口'
    const data = { ...props.params, page: unref(page), size: unref(pagesize) };
    console.log('请求参数', data)
    const res = await props.request({
      data
    })
    console.log('list组件', res)
    if (res.code === 2000) {
      // aaa.value = '调用接口成功'
      console.log(res)
      //获取到list的键名
      const listKey = Object.keys(res.data).filter(item => item !== 'count')[0]
      //合并数组
      list.value = [...list.value, ...(res.data[listKey] ?? [])];
      total.value = res.data.count
      //已经加载完全
      if (page.value * pagesize.value >= total.value) {
        finished.value = true
      }
    }
    // aaa.value = 'loding按钮关闭'
    loading.value = false
  }
  //刷新列表数据
  const refresh = async () => {
    finished.value = false
    list.value = []
    page.value = 1
    total.value = 0
    await getList()
  }

  //监听该页面用户下拉刷新事件
  onPullDownRefresh(async () => {
    if (!props.refresh) return
    await refresh()
    //停止当前页面的下拉刷新
    uni.stopPullDownRefresh()
  })


  //监听用户上拉加载更多
  onReachBottom(() => {
    if (!props.loadmore) return
    if (page.value * pagesize.value >= total.value || loading.value) return
    // if(finished) return 
    page.value += 1
    getList()
  })

  onMounted(() => {
    getList()
  })



  //暴露自己的属性
  defineExpose({
    setPage,
    setSize,
    getList,
    refresh
  })
</script>

<style lang="less" scoped>

</style>

3. 在组件中使用

<!-- 展示商家列表 -->
<List :request="getProxyList" ref="list" :params="queryparams" text='选择区域搜索更多'>
     <template #default="{ list }">
           <MerchantItem v-for="(item, index) in list" :item="item" :key="index"/>
     </template>
</List>

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐