GithubHelp home page GithubHelp logo

tingyuxuan2302 / taro3-virtual-list Goto Github PK

View Code? Open in Web Editor NEW
181.0 2.0 26.0 3.4 MB

基于taro3封装的虚拟列表,对列表节点不等高以及白屏等问题支持友好,无计算量,性能优异,支持各大小程序以及h5页面

License: MIT License

TypeScript 70.20% JavaScript 24.78% SCSS 0.56% HTML 4.46%

taro3-virtual-list's Introduction

欢迎交流

微信:brown_7778

基于Taro3的虚拟列表

安装
使用方法
参数说明
注意事项
白屏问题
组件原理

如果该组件库对您的日常开发有所帮助或者说为您提供了一定的开发思路,希望可以随手点一个star🌟,以此来激励作者输出更优质的代码👏

安装

npm i -D taro-virtual-list

使用方法

试用场景一:一次性请求到所有数据(即listType="single")

import { TaroVirtualList } from 'taro-virtual-list'

export default function Demo(): JSX.Element {
  // 渲染列表Item
  const renderFunc = (item, index, pageIndex) => {
    return (
      <View className="el">{`当前是第${item}个元素,是第${pageIndex}屏的数据`}</View>
    )
  }
  const handleBottom = () => {
    console.log('触底了')
  }
  const handleComplete = () => {
    console.log('加载完成')
  }
  return (
    <View>
      <TaroVirtualList
        list={list}
        onRender={renderFunc}
        onBottom={handleBottom}
        onComplete={handleComplete}
        scrollViewProps={{
          style: {
            "height": '100vh',
          },
        }}
      />
    </View>
  )

}

试用场景二:数据是分页请求(即listType="multi")

import { TaroVirtualList } from 'taro-virtual-list'

export default function Demo(): JSX.Element {
  // 渲染列表Item
  const renderFunc = (item, index, pageIndex) => {
    return (
      <View className="el">{`当前是第${item}个元素,是第${pageIndex}屏的数据`}</View>
    )
  }
  const onPageScrollToLower = () => {
    // 执行分页数据请求
  }
  return (
    <View>
      <TaroVirtualList
        autoScrollTop={false}
        listType="multi"
        list={list}
        pageNum={页码}
        segmentNum={每页的数据量}
        onRender={renderFunc}
        scrollViewProps={{
          onScrollToLower: onPageScrollToLower,
          lowerThreshold: 50,
          style: {
            "height": '100vh',
          },
        }}
      />
    </View>
  )

}

参数说明

Props

参数 类型 默认值 必填 说明
list Array - 列表数据
listId String "zt-virtial-list" 虚拟列表唯一id(防止同一个页面有多个虚拟列表导致渲染错乱)
listType String "single" 传入组件内的list类型
single:一次性传入列表所有数据
multi:从服务端分页请求,合并之后传入组件
pageNum Number 1 当前页码,当list是通过服务端分页获取的时候必传,最小值是1
segmentNum Number 10 自定义二维数组每一维度的数量,默认10,当list是通过服务端分页获取的时候,推荐传每页的数据量,且必传
autoScrollTop Boolean true 组件内部是否需要根据list数据变化自动滚动至列表顶部
screenNum Number 2 指定监听页面显示区域基准值,例如2,则组件会监听 2 * scrollHeight高度的上下区域范围(该值会影响页面真实节点的渲染数量,值越大,白屏几率越小,但是页面性能也就越差)
scrollViewProps Object - 自定义scrollView的参数,会合并到组件内部的scrollView的参数里

Events

参数 回调参数 默认值 必填 说明
onRender (item, index, segmentIndex) => {}
item: 列表的单个数据项的值;
index:列表的单个数据项的index;
segmentIndex:当前二维数组维度的index
- 列表的渲染回调,用于自定义列表Item -
onBottom - - 列表是否已经触底回调,注:只有在listType=single时有效
onComplete - - 列表是否已经把全部数据加载完成的回调
onRenderTop - - 列表上部分内容渲染回调,用于渲染插入虚拟列表上边的内容
onRenderBottom - - 列表下部分内容渲染回调,用于渲染插入虚拟列表下边的内容
onRenderLoad - - 用于上拉到底部渲染底部loading样式的回调
onGetScrollData (res) => {} - 获取滚动信息,以传入的listId作为key,默认key是“zt-virtial-list”,目的是让用户可以自定义组件的滚动高度,以此解决NervJS/taro#8466的问题

注意事项

  1. 当listType="single"时,组件默认当外部传入的list引用发生变更的话,会重新渲染整个列表,如果不想重新渲染,则外部只需要修改list内部对象的属性值即可,不要更换list的引用地址
  2. 如果想禁止组件内部自动滚动至顶部的功能,将autoScrollTop置为false,此时需要用户手动控制列表滚动高度,可通过onGetScrollData回调获取当前列表滚动数据,注意该数据结构有所不同噢
  3. 当遇到服务端分页请求获得list的情况,listTypepageNumsegmentNum必传,autoScrollTop置为false,在scrollViewProps中传入onScrollToLower函数
  4. onRenderBottom渲染的内容会在虚拟列表所有数据渲染完成之后才会调用
  5. 该组件默认支持拿到全部数据进行渲染,如果用户的数据是分页请求的,需要将autoScrollTop参数置为false,否则每请求一次数据,列表就会默认置顶
  6. 设置scrollViewProps参数的时候请注意:
  • 最好给个容器高度
  • 当listType=single,如果想触发onScrollToLower方法,可以尝试使用onBottom回调代替(因为组件内部已经使用了onScrollToLower方法,如果外部再定义,会导致代码冲突,组件上拉加载失效)

体验优化

白屏问题

问题:此组件在快速滑动页面的时候难免会出现短暂白屏问题,这个问题目前世面上是没有很好的解决方案的
优化:可以做一个骨架屏放在列表的下方(即列表组件覆盖在骨架屏上方),此时可以将zt-main-list这个元素背景色置为transparent,这是在快速滑动过程中,下方的骨架屏就可以漏出来了,给用户带来一个正在加载数据的效果,缓解用户焦虑(ps:如果有更好的方案,欢迎交流)

感谢

如果用着感觉还不错,欢迎赐予一枚star,以此来激励作者输出更多优质代码,造福一方😄

为啥要开发该组件

  1. 列表页数据量过多,一次性渲染完成后页面节点数量过大,造成页面渲染卡顿,渲染完成之后操作页面数据也会异常卡顿;
  2. 官方虚拟列表(3.2.1)存在一定的渲染bug,特别是针对列表节点不等高,存在诸多问题,比如节点闪动、滚动过快造成无限加载、白屏率较高等;

该组件适用场景

  1. 页面节点渲染较多(主要是列表页);
  2. 针对列表页节点不等高具有更好的支持;

版本

1.0.6

  • 支持服务端分页获取数据渲染

1.0.4

  • 添加onGetScrollData回调获取列表滚动数据

1.0.3

  • 添加autoScrollTop控制列表内部滚动逻辑

组件原理

  1. 处理数据:将传入的list分割成二维数组,初始化的时候只加载二维数组的第一项,随着页面滚动,会依次加入对应维度的数据(加快了初始化渲染速度);
  2. 可视区域监听:利用Taro.createIntersectionObserver监听当前可视区域,将不在可视区域内的那一维度的数据改成该维度数据所占的视图高度(进而减少了setState的数据量);
  3. 渲染:将不在可视区域内的数据利用一个节点占高(减少了节点渲染数量);

taro3-virtual-list's People

Contributors

tingyuxuan2302 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

taro3-virtual-list's Issues

文件名有误,在大小写敏感的文件系统中无法加载类型

文件名有误,在大小写敏感的文件系统中无法加载类型

diff:

diff --git a/node_modules/taro-virtual-list/@types/index.d.ts b/node_modules/taro-virtual-list/@types/index.d.ts
index f149365..4b3d680 100644
--- a/node_modules/taro-virtual-list/@types/index.d.ts
+++ b/node_modules/taro-virtual-list/@types/index.d.ts
@@ -1 +1 @@
-export { default as TaroVirtualList } from './virtualList'
+export { default as TaroVirtualList } from './VirtualList'

This issue body was partially generated by patch-package.

当数据源从多变成少的时候,scrollView的滚动高度,不会随着改变

有一个问题,当数据源从多变成少的时候,scrollView的滚动高度,不会随着改变,并且上滑的时候 会疯狂的闪屏

const isLowerThreshold = total >= query.rowsPerPage;

<TaroVirtualList
  list={list}
  listId='legworkId'
  segmentNum={isLowerThreshold ? query.rowsPerPage : total}
  autoScrollTop={autoScrollTop}
  listType='multi'
  pageNum={query.pageNo}
  className={styles.indexListContainer}
  scrollViewProps={{
    onScrollToLower: onPageScrollToLower,
  }}
  onRender={(item, index) => {
    return <ListItem data={item} index={index} />;
  }}

isLowerThreshold 想着如果获取到的数据只有个位数的话,每次展示的条数也应当进行调整,当时发现没什么用
autoScrollTop也是为了点击筛选的时候自动滚动到顶部设置的

大佬有空帮忙看看这个问题

single模式打开页面很慢

single模式:1000条数据模拟,
打开页面速度很慢(Taro官方的VirtualList打开页面很快),打开后滑动起来很流畅没问题
是否慢在计算总高度?希望优化一下

以下是代码:

1676172520770

小程序Sticky支持

小程序中scroll-view中的直接内容如果使用position: sticky会在大于scroll-view视窗高度时被顶开。

目前比较通用的解决方案是,在scroll-view中直接包裹一层View标签,如:

<ScrollView>
  <View>
    ...content
  </View>
</ScrollView>

如此改进后,以下API将可以支持使用position: sticky:

  • onRenderTop
  • onRenderBottom
  • onRenderLoad

为什么按示例,使用不成功呢

image

按照示例代码直接拷贝过去,显示如上图所示,是我哪里不对吗,下面是我的代码

import React, {useState, useEffect} from 'react'
import {View} from "@tarojs/components"
import {TaroVirtualList} from 'taro-virtual-list'

export default function Cart() {
  // 模拟list数据
  const [list, setList] = useState([])

  // 设置list
  useEffect(() => {
    const arr = []
    Array(84).fill(0).forEach((item, index) => {
      arr.push(index)
    })
    setList(arr)
  }, [])
  // 渲染列表Item
  const renderFunc = (item, index, pageIndex) => {
    return (
      <View className="el">{`当前是第${item}个元素,是第${pageIndex}屏的数据`}</View>
    )
  }
  const handleBottom = () => {
    console.log('触底了')
  }
  const handleComplete = () => {
    console.log('加载完成')
  }
  console.log(list);
  return (
    <View>
      <TaroVirtualList
        list={list}
        onRender={renderFunc}
        onBottom={handleBottom}
        onComplete={handleComplete}
        scrollViewProps={{
          style: {
            "height": '100vh',
          },
        }}
      />
    </View>
  )

}

当页面中有多个 TaroVirtualList 时如何处理

当页面中有多个 TaroVirtualList 时,第一个 TaroVirtualList 会影响第二个的展现。具体表现为:

  1. 第二个 TaroVirtualList 会从列表数据的第10个开始显示,而且之前有大段空白
  2. 第一个 TaroVirtualList 触底时不能自动显示新数据

不是很清楚,这是bug,还是我使用的方式不对?

列表如何重置

大佬,我有个小需求是tab切换改变列表中的数据,所有tab共用一个virtual-list,所以需要重置所有状态

taro3.6.8滚动问题

taro3.6.8,我获取分页数据时,获取第二页之后自动回滚到顶部,并且之后滚动到第二页就会回滚到顶部

image image

IphoneX 列表闪屏

你好, 目前在使用的时候, 发现在IphoneX上一直闪屏,其他手机上目前还没有发现。有没有什么方法可以解决IphoneX上闪屏的问题。感谢!

下拉刷新,twoList数据未重置

分页加载列表时,当上拉加载两页后,再下拉刷新,会依旧加载两页数据。查看源码,是formatMultiList方法中twoList数据并未重置为空,导致第一页数据更新,但是第二页数据依然存在。

安装问题

运行npm i -D taro-virtual-list的时候报如下错误
`npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR! peer react@"^18.2.0" from [email protected]
npm ERR! node_modules/react-dom
npm ERR! peer react-dom@">=16.6.0" from [email protected]
npm ERR! node_modules/react-transition-group
npm ERR! react-transition-group@"^4.4.2" from @nutui/[email protected]
npm ERR! node_modules/@nutui/nutui-react-taro
npm ERR! @nutui/nutui-react-taro@"^1.4.9" from the root project
npm ERR! peer react-dom@"^16.8.0 || ^17.0.0 || ^18.0.0" from @react-spring/[email protected]
npm ERR! node_modules/@react-spring/web
npm ERR! @react-spring/web@"^9.3.2" from @nutui/[email protected]
npm ERR! node_modules/@nutui/nutui-react-taro
npm ERR! @nutui/nutui-react-taro@"^1.4.9" from the root project
npm ERR! 1 more (the root project)
npm ERR! peer react@"^18.0.0" from [email protected]
npm ERR! node_modules/react-reconciler
npm ERR! react-reconciler@"0.27.0" from @tarojs/[email protected]
npm ERR! node_modules/@tarojs/react
npm ERR! @tarojs/react@"3.6.2" from the root project
npm ERR! 10 more (react-transition-group, @nutui/nutui-react-taro, ...)
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0 || 16.9.0-alpha.0" from [email protected]
npm ERR! node_modules/mobx-react
npm ERR! mobx-react@"^6.1.4" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/react
npm ERR! peer react@"^16.8.0 || 16.9.0-alpha.0" from [email protected]
npm ERR! node_modules/mobx-react
npm ERR! mobx-react@"^6.1.4" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/fangyp/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR! /.npm/_logs/2023-03-05T10_28_50_274Z-debug-0.log
`

    "@tarojs/taro": "3.6.2",
    "mobx": "^4.8.0",
    "mobx-react": "^6.1.4",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"

formatMultiList

formatMultiList 只更改了当前pageNum。如果 我前一页的数据变更时,不会变更

listType为multi时滚动异常

一直往下滑动会出现白屏闪现然后回退到上一屏,比如第74个元素的时候,会白屏闪下然后滚回到第59个元素。
应该是ios的会有问题,安卓机型试了两个正常,苹果的试了11与8都会有问题
`
import React, { useState, useEffect } from "react";
import { View } from "@tarojs/components";
import { TaroVirtualList } from "taro-virtual-list";

import styles from "./sports-team-list.module.styl";

export default function SportsTeamList(): JSX.Element {
const [list, setList] = useState<number[]>([]);
const [pageNum, setPageNum] = useState(1);

useEffect(() => {
const arr: number[] = [];
Array(10)
.fill(0)
.forEach((item, index) => {
arr.push(index);
});
setList(arr);
}, []);
// onReachBottom() {
// console.log('触底了----')
// // this.renderNext()
// this.setState({
// isBottom: true,
// })
// }
// getIsBottomStatus = (status) => {
// this.setState({
// isBottom: status,
// })
// }
const renderFunc = (item, index, pageIndex) => {
return (
{当前是第${item}个元素,是第${pageIndex}屏的数据}
);
};
// const handleBottom = () => {
// console.log('触底了')
// }
const handleComplete = () => {
console.log("加载完成");
};
// const handleGetScrollData = (e) => {
// console.log('scroll-data', e)
// }
const onRenderTop = () => {
return 头部;
};
const handleScrollToLower = () => {
console.log("chudidi");
const arr: number[] = [];
Array(10)
.fill(0)
.forEach((item, index) => {
arr.push(list.length + index);
});
let _list = [...list];
_list = _list.concat(arr);
setTimeout(() => {
setList(_list);
}, 1000);
setPageNum(pageNum + 1);
};
const handleRenderLoad = () => {
return "数据载入中...";
};
return (

{/* 145 */}
<TaroVirtualList
list={list}
pageNum={pageNum}
autoScrollTop={false}
segmentNum={10}
screenNum={3}
onRender={renderFunc}
// onBottom={handleBottom}
onComplete={handleComplete}
// onGetScrollData={handleGetScrollData}
listType="multi"
onRenderTop={onRenderTop}
onRenderLoad={handleRenderLoad}
scrollViewProps={{
style: {
height: "100vh",
},
lowerThreshold: 30,
onScrollToLower: handleScrollToLower,
}}
/>

);
}
`

结合TaroUI的Tabs,切换Tab后不渲染第一页的数据

<AtTabs current={currentTab} tabList={tabList} onClick={switchTab}> <AtTabsPane current={currentTab} index={0} customStyle={{ backgroundColor: "#F2F2F2" }} > <TaroVirtualList autoScrollTop={false} listType='multi' list={listData[0].list} pageNum={listData[0].pIndex} segmentNum={pageSize} screenNum={1} listId='id' onRender={(cp) => (<Item {...cp} key={cp.id} onShare={() => openShare(cp)} />)} scrollViewProps={{ onScrollToLower: () => onPageScrollToLower(0), lowerThreshold: 50, style: { height: '100vh', marginBottom: '30px', marginTop: '82rpx' }, }} /> </AtTabsPane> <AtTabsPane current={currentTab} index={1}> <TaroVirtualList autoScrollTop={false} listType='multi' list={listData[1].list} pageNum={listData[1].pIndex} segmentNum={pageSize} screenNum={1} listId='id' onRender={(cp) => (<Item {...cp} key={cp.id} onShare={() => openShare(cp)} />)} scrollViewProps={{ onScrollToLower: () => onPageScrollToLower(1), lowerThreshold: 50, style: { height: '100vh', marginBottom: '30px', marginTop: '82rpx' }, }} /> </AtTabsPane> </AtTabs>

结合TaroUI的Tabs组件,当在第二个Tab内滑到第2页,切换到第一个Tab,再切换回第二个Tab,此时不渲染第1页的数据,只有占位
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.