Taro虚拟瀑布流组件详解与使用指南

Viewed 0

多列表渲染(虚拟瀑布流)

多列表渲染(虚拟瀑布流)与虚拟列表原理一致,通过只渲染当前可视区域的视图,可以极大程度提升多列表渲染时的性能。注意:v3.6.10 及以下版本不支持。

示例

基础示例

在 React 或 Vue 等框架中,可以从 @tarojs/components-advanced 引入虚拟瀑布流(VirtualWaterfall)组件:

import { VirtualWaterfall } from '@tarojs/components-advanced'

一个最简单的长列表组件示例如下,其中 VirtualWaterfall 的 6 个属性都是必填项:

function buildData(offset = 0) {
  return Array(100)
    .fill(0)
    .map((_, i) => i + offset)
}

const Row = React.memo(({ id, index, data }) => {
  return (
    <View id={id} className={index % 2 ? 'ListItemOdd' : 'ListItemEven'}>
      Row {index} : {data[index]}
    </View>
  )
})

export default class Index extends Component {
  state = {
    data: buildData(0),
  }

  render() {
    const { data } = this.state
    const dataLen = data.length
    return (
      <VirtualWaterfall
        height={800}
        width="100%"
        item={Row}
        itemData={data}
        itemCount={dataLen}
        itemSize={100}
      />
    )
  }
}

无限滚动

实现无限滚动时,只需在列表滚动到底部时追加数据。以下示例展示了如何在滚动到底部时加载更多数据:

const Row = React.memo(({ id, index, data }) => {
  return (
    <View id={id} className={index % 2 ? 'ListItemOdd' : 'ListItemEven'}>
      Row {index} : {data[index]}
    </View>
  )
})

function buildData(offset = 0) {
  return Array(100)
    .fill(0)
    .map((_, i) => i + offset)
}

export default class Index extends Component {
  state = {
    data: buildData(0),
  }

  loading = false

  listReachBottom() {
    Taro.showLoading()
    this.loading = true
    setTimeout(() => {
      const { data } = this.state
      this.setState(
        {
          data: data.concat(buildData(data.length)),
        },
        () => {
          this.loading = false
          Taro.hideLoading()
        }
      )
    }, 1000)
  }

  render() {
    const { data } = this.state
    const dataLen = data.length
    const itemSize = 100
    return (
      <VirtualWaterfall
        className="List"
        height={500}
        item={Row}
        itemData={data}
        itemCount={dataLen}
        itemSize={itemSize}
        width="100%"
        onScroll={({ scrollDirection, scrollOffset }) => {
          if (
            !this.loading &&
            scrollDirection === 'forward' &&
            scrollOffset > (dataLen - 5) * itemSize + 100
          ) {
            this.listReachBottom()
          }
        }}
      />
    )
  }
}

Props

column

类型: number
瀑布流占用列数量,默认值依照 width / columnWidth ||= 2 计算。

columnWidth

类型: number
瀑布流单列宽度,默认值依照 width / column 计算。

height

类型: number | string
列表的高度。

width

类型: number | string
列表的宽度。

item (必填)

类型: ReactComponent
推荐在 React 中使用 React.memoReact.PureComponent 进行优化,Vue 中也有相应优化方式。组件的 props 包括 idindexdataisScrolling(当 useIsScrollingtrue 时返回布尔值)。

itemCount (必填)

类型: number
列表的长度。

itemData (必填)

类型: Array<any>
渲染数据。

itemSize (必填)

类型: number | (index?: number, itemData?: Array<any>) => number
列表单项的大小。

unlimitedSize

类型: boolean
解开高度列表单项大小限制,默认使用 itemSize(注意初始高度与实际高度差异过大会导致隐患)。

position

类型: 'absolute' | 'relative' | 'brick'
布局方式,默认采用 "absolute"。其中 absolute 为绝对定位,relative 为相对定位并插入前置节点替代未显示单项的高度,brick 为相对定位但保留未显示单项节点(可能影响性能)。

initialScrollOffset (默认: 0)

类型: number
初始滚动偏移值。

overscanDistance (默认: 50)

类型: number
在可视区域之外预渲染的距离,值越高则白屏概率越小但滚动性能可能下降,建议至少大于等于 itemSize 的最大值。

placeholderCount (默认: 0)

类型: number
在可视区域之外占位的列表单项数量,值越高则白屏概率越小但性能可能下降。

upperThreshold (默认: 50)

类型: number
距离顶部多远时触发 onScrollToUpper 函数,单位为 px

lowerThreshold (默认: 50)

类型: number
距离底部多远时触发 onScrollToLower 函数,单位为 px

useIsScrolling

类型: boolean
是否向 item 组件注入 isScrolling 属性,适用于实现滚动骨架屏等场景。

enhanced (默认: true)

类型: boolean
通过 ScrollViewContext 优化组件滚动性能,部分平台可能不支持。

Events

scroll 事件

列表滚动时调用,参数对象包含 scrollDirection(滚动方向)、scrollOffset(滚动距离)和 scrollUpdateWasRequested(是否由 scrollToscrollToItem 触发)。

onScrollNative

类型: Function
调用平台原生的滚动监听函数。

onScrollToUpper

类型: Function
滚动到顶部时调用函数。

onScrollToLower

类型: Function
滚动到底部时调用函数。

Slots & Components

列表插槽

  • renderTop: 顶部区域组件,类型为 ReactComponent<{ id: string }>
  • renderBottom: 底部区域组件,类型为 ReactComponent<{ id: string }>

outerElementType

列表外部容器组件类型,默认值为 ScrollView,不建议替换为 View

innerElementType

列表内部容器组件类型,默认值为 View

itemElementType

列表子节点容器组件类型,默认值为 View

Native Props

组件 ID

类型: string
根组件 ID,用于标识组件,不传入时会自动生成。

组件 CSS 类

根组件 CSS 类。

组件 CSS 样式

类型: Style
根组件的 CSS 样式。

其它 ScrollView 参数

除上述参数外,所有 ScrollView 组件的参数都可以传入 VirtualWaterfall 组件,冲突时优先使用文档描述的参数。

Methods

通过 React.createRef() 创建 ref 并挂载到 VirtualWaterfall 上,可以访问内部方法:

export default class Index extends Component {
  state = {
    data: buildData(0),
  }

  list = React.createRef()

  componentDidMount() {
    const list = this.list.current
    list.scrollTo()
    list.scrollToItem()
  }

  render() {
    const { data } = this.state
    const dataLen = data.length
    return (
      <VirtualWaterfall
        height={500}
        width="100%"
        item={Row}
        itemData={threads}
        itemCount={threads.length}
        itemSize={100}
      />
    )
  }
}

scrollTo

(scrollOffset: number, enhanced?: boolean): void
滚动到指定的地点,enhanced 默认为 props 传入的 enhanced 值。

scrollToItem

(index: number, align: string = "auto", enhanced?: boolean): void
滚动到指定的条目。align 参数可选值包括:

  • auto: 尽可能滚动距离最小保证条目在可视区域中。
  • smart: 条目部分在可视区域时最小滚动,完全不在时居中显示。
  • center: 让条目在可视区域居中显示。
  • end: 让条目在可视区域末尾显示。
  • start: 让条目在可视区域开始显示。
    enhanced 默认为 props 传入的 enhanced 值。
0 Answers