chanjet-virtual-list
v1.0.2
Published
基于chanjet-scroller提供滚动的虚拟列表
Downloads
4
Readme
VirtualList
VirtualList是一个基于 chanjet-scroller
实现的用于提供大数据量的虚拟列表.
安装
如果你想独立使用VirtualList, 直接安装包并在代码中引用即可
安装
npm install chanjet-virtual-list
引用
import VirtualList from "chanjet-virtual-list"
如果你正在使用 chanjet-ui
库, 那么你可以直接在 chanjet-ui
库中使用
import VirtualList from "chanjet-ui/lib/components/VirtualList"
使用
使用前须知
虚拟列表是利用固定数量的元素来渲染趋近于无限数据的解决方案, 和常规列表不同, 首选需要明确几个概念:
- estimateHeight 预估行高
- itemRenderer 列表行渲染
- redundancy 冗余数量
- size 列表总行数
estimateHeight 预估行高
由于虚拟列表不渲染所有行, 所以整体高度需要进行预估. 这就是我们需要设置预估行高的原因. 当行元素没有被渲染时, 我们会使用预估行高来进行高度计算, 当行元素被真正渲染时, 我们会使用实际高度进行计算.
itemRenderer 列表行渲染
根据滚动位置计算出需要渲染的元素后, 我们会调用 itemRenderer
来获取实际需要进行渲染的React组件.
itemRenderer是一个函数, 分别接收 index, key
作为参数, 返回一个 React
组件.
由于我们并不接收列表数据, 所以我们会通过 itemRenderer
里的index参数来告诉你, 现在需要使用第几条顺序, 这个index仅仅代表它在列表中的行数, 排序规则应该由你来决定.
const data = [
{name: 'TonyJiang1', power:10, magic:10},
{name: 'TonyJiang2', power:8, magic:2},
...
]
//参数index表示当前需要显示的数据的索引号, 从0开始
//参数key表示在React中所分配的可用于重用和排序的固定key.
const itemRenderer = function(index, key){
//通过index来获取当前所需要的数据
return (
<div className="item">
<span className="item-name">{data[index].name}</span>
<span className="item-power">{data[index].power}</span>
<span className="item-magic">{data[index].magic}</span>
</div>
);
}
redundancy 冗余数量
如果只根据屏幕高度来计算需要渲染的行, 那么在低端机上, 滚动速度过快时, 会出现白屏, 冗余数量就是设置除了必要的显示数量外, 还额外渲染的数量, 来保证在滚动过程中用户的体验是完美的.
在正常情况下冗余元素会被我们平均的添加于列表前后.
size 列表总行数
所需要渲染的总行数
明确了这几个概念后, 就可以开始使用虚拟列表了 : )
开始使用
使用虚拟列表需要设置上述的四项才可以正常运行:
通过 props
设置 itemRenderer
来定义每一行元素如何进行渲染;
通过 props
设置 estimateHeight
来定义行元素的预估行高;
通过 props
设置 redundancy
来定义冗余元素数量;
通过 props
设置 size
来定义数据总数;
import React from 'react';
import VirtualList from "chanjet-virtual-list";
class DemoPage extends React.Component{
//示例数据
data = [
{name: 'TonyJiang1', power:10, magic:10},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
...
];
//react组件的itemRenderer方法, 其余代码省略
itemRenderer(){}
//react组件的render方法, 其余代码省略
render(){
//虚拟列表的滚动是基于chanjet-scroller实现的, 所以显示范围的定义可以参考Scroller.
return (
<div style={{width:200,height:200}}>
<VirtualList
itemRenderer={this.itemRenderer.bind(this)}
size=(data.length)
estimateHeight={80}
redundancy={10}
/>
</div>
);
}
}
顶部下拉刷新
启用
顶部下拉刷新的功能和 Scroller
一致
唯一要注意的区别就是, 在调用回调函数时, 需要把新的数据大小 size
传递回去.
import React from 'react';
import VirtualList from "chanjet-virtual-list";
class DemoPage extends React.Component{
//示例数据
data = [
{name: 'TonyJiang1', power:10, magic:10},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
...
];
//react组件的itemRenderer方法, 其余代码省略
itemRenderer(){}
//回调接受第一个参数作为外部过程完成后的回调函数
onRefresh(done){
//这里使用Promise是为了表示,需要在外部业务处理完成后再调用回调的顺序关系
Promise.resolve(() => {
//具体更新数据代码, 省略
...
}).then(() => {
//刷新完数据后, 回调里一定要传入新的数据大小
done(this.data.length);
});
}
//react组件的render方法, 其余代码省略
render(){
//虚拟列表的滚动是基于chanjet-scroller实现的, 所以显示范围的定义可以参考Scroller.
return (
<div style={{width:200,height:200}}>
<VirtualList
itemRenderer={this.itemRenderer.bind(this)}
refreshHandler={this.onRefresh.bind(this)}
size=(data.length)
estimateHeight={80}
redundancy={10}
/>
</div>
);
}
}
底部上拉加载更多
底部上拉加载更多的功能和 Scroller
一致
唯一要注意的区别就是, 在调用回调函数时, 需要把新的数据大小 size
传递回去.
import React from 'react';
import VirtualList from "chanjet-virtual-list";
class DemoPage extends React.Component{
//示例数据
data = [
{name: 'TonyJiang1', power:10, magic:10},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
{name: 'TonyJiang2', power:8, magic:2},
...
];
//react组件的itemRenderer方法, 其余代码省略
itemRenderer(){}
//回调接受第一个参数作为外部过程完成后的回调函数
onLoadMore(done){
//这里使用Promise是为了表示,需要在外部业务处理完成后再调用回调的顺序关系
Promise.resolve(() => {
//具体加载数据代码, 省略
...
}).then(() => {
//刷新完数据后, 回调里一定要传入新的数据大小
done(this.data.length);
});
}
//react组件的render方法, 其余代码省略
render(){
//虚拟列表的滚动是基于chanjet-scroller实现的, 所以显示范围的定义可以参考Scroller.
return (
<div style={{width:200,height:200}}>
<VirtualList
itemRenderer={this.itemRenderer.bind(this)}
moreHandler={this.onLoadMore.bind(this)}
size=(data.length)
estimateHeight={80}
redundancy={10}
/>
</div>
);
}
}
Props
| 属性 | 类型 | 描述 | 是否必填 | 默认值 | | -------------- | -------- | ------------------------ | ---- | ---- | | itemRenderer | function | 每一行实际需要渲染的元素,返回一个React组件 | 必填 | - | | estimateHeight | number | 行元素的预估行高 | 必填 | - | | size | number | 数据总数,根据size进行高度计算 | 必填 | - | | redundancy | number | 冗余数量 | 非必填 | 10 |