Skip to content

pull-to-refresh 下拉刷新上拉加载

下拉刷新和上拉加载是常见的在移动应用和Web应用中实现数据更新和加载更多内容的交互手段。下拉刷新允许用户通过在列表或页面顶部向下滑动来触发数据的刷新,而上拉加载则允许用户通过在列表或页面底部向上滑动来加载更多数据。

Props参数

名称类型是否必传默认值描述
stateMMPullToRefreshState-状态
用于控制组件行为。比如刷新、加载更多
heightnumber-容器高度
下拉刷新必须指定一个高度。
大部分情况下组件内会自动根据距离顶部距离计算出容器剩余高度作为组件高度。
但是有些特定情况。造成两个滚动条的时候。你可能需要手动指定容器高度
noMoreboolean-是否没有更多数据。
noMoreTextReactNode-没有更多的文案
noMoreTextDelaynumber-没有更多的文案延迟显示时间

毫秒
用于配合瀑布流组件内部100毫秒的渲染延迟
emptyReactNode-空组件
当组件数据为空时。显示的组件
renderFooterReactNode-渲染底部 低于无更多
bottomboolean-是否计算底部距离
enablePullbooleantrue是否启用下拉刷新
showScrollbarbooleantrue是否显示滚动条
onRefresh() => void | Promise<void>-刷新事件回调
onScrollToLower() => void-滚动到地步回调

示例

tsx
import { View } from '@tarojs/components'
import MMPullToRefresh from '~/components/pull-to-refresh'
import MMPageContainer from '../_components/page-container'
import useMMPullToRefresh from '~/components/pull-to-refresh/useMMPullToRefresh'
import { guid } from '~/components/utils'
import MMCard from '~/components/card'
import PageDemoBlock from '../_components/page-demo-block'
import { MMButton, MMEmpty } from '~/components'
import { useEffect, useState } from 'react'

export default () => {
  const [noData, setNoData] = useState(false)
  const [enablePull, setEnablePull] = useState(true)
  const [info, props] = useMMPullToRefresh({
    initRequest: false,
    async getData(data) {
      const pageIndex = data.pageNum
      if (noData) {
        return { data: { isLastPage: true, list: [] } }
      }

      const list = await mockGetData()
      if (pageIndex === 3) {
        return {
          data: { isLastPage: true, list }
        }
      }
      return {
        data: { isLastPage: false, list }
      }
    }
  })

  useEffect(() => {
    props.onRefresh()
  }, [noData])

  return (
    <MMPageContainer title="下拉刷新上拉加载" constStyle={{ padding: 0 }}>
      <MMPullToRefresh
        {...props}
        noMoreText="已经到底啦~~~"
        enablePull={enablePull}
        // 展示空组件
        empty={
          info.isEmpty && (
            <View>
              <MMEmpty text="点击切换数据" fixed onClick={() => setNoData((pre) => !pre)} />
            </View>
          )
        }
        renderFooter={<View>底部</View>}
      >
        {info.list.map((item, index) => {
          if (index === 0) {
            return (
              <PageDemoBlock title="介绍" key={item.text} style={{ marginBottom: 5 }}>
                下拉刷新和上拉加载是常见的交互方式,用于在移动应用或网页中加载和展示更多数据。
              </PageDemoBlock>
            )
          }

          if (index === 1) {
            return (
              <PageDemoBlock title="使用" key={item.text} style={{ marginBottom: 5 }}>
                <View style={{ display: 'flex', flexWrap: 'wrap' }}>
                  <View>组件参数较多。我们建议你使用</View>
                  <View style={{ fontWeight: 'bold' }}>useMMPullToRefresh</View>
                  <View>钩子函数一起使用</View>
                </View>
              </PageDemoBlock>
            )
          }

          if (index === 2) {
            return (
              <PageDemoBlock title="示例" key={item.text} style={{ marginBottom: 5 }}>
                <View style={{ display: 'flex', flexWrap: 'wrap' }}>
                  <MMButton onClick={() => setNoData((pre) => !pre)}>切换无数据</MMButton>
                  <MMButton onClick={() => setEnablePull((pre) => !pre)}>{enablePull ? '允许' : '不允许'}下拉刷新</MMButton>
                </View>
              </PageDemoBlock>
            )
          }

          return (
            <MMCard key={item.text} style={{ marginBottom: 5 }}>
              {item.text}
            </MMCard>
          )
        })}
      </MMPullToRefresh>
    </MMPageContainer>
  )
}

function mockGetData() {
  return new Promise<any[]>((resolve) => {
    const list = Array.from({ length: 20 }).map((it) => ({ text: guid() }))
    setTimeout(() => {
      resolve(list)
    }, 1000)
  })
}