VirtualList 虚拟滚动列表

如果项目中使用的是 0.x 版本的基础组件(@icedesign/base, @ali/ice, @alife/next),请在左侧导航顶部切换组件版本。

安装方法

  1. 在命令行中执行以下命令npm install @alifd/next@latest -S

开发指南

何时使用

主要用于解决大数据情况下的渲染速度问题。组件的设计思想可以看这篇文章 https://zhuanlan.zhihu.com/p/55329238

API

VirtualList

参数说明类型默认值
children渲染的子节点any-
minSize最小加载数量Number1
pageSize一屏数量Number10
itemsRenderer父渲染函数,默认为 (items, ref) => {items}签名:Function() => voidFunction(items, ref) => <ul ref={ref}>{items}</ul>
threshold缓冲区高度Number100
itemSizeGetter获取item高度的函数签名:Function() => voidFunction-
jumpIndex设置跳转位置,需要设置 itemSizeGetter 才能生效, 不设置认为元素等高并取第一个元素高度作为默认高Number0

代码示例

简单用法

使用 VirtualList 最简单的例子。

VirtualList 虚拟滚动列表 - 图1

查看源码在线预览

  1. import { VirtualList } from '@alifd/next';
  2. const dataSource = [];
  3. const generateLi = (index = 'index') => {
  4. const data = [];
  5. if (index % 3 === 0) {
  6. return <li key={`key-${index}`} style={{lineHeight: '30px', background: '#5f83ff', color: '#fff'}}>key-{index}</li>;
  7. } else {
  8. return <li key={`key-${index}`} style={{lineHeight: '20px'}}>key-{index}</li>;
  9. }
  10. };
  11. for (let i = 0; i < 1000; i++) {
  12. dataSource.push(generateLi(i));
  13. }
  14. const demo = (
  15. <div className={'virtual-box'}>
  16. <VirtualList>
  17. {dataSource}
  18. </VirtualList>
  19. </div>
  20. );
  21. ReactDOM.render(demo, mountNode);
  1. .virtual-box {
  2. height: 200px;
  3. width: 200px;
  4. border: 1px solid #ddd;
  5. overflow: auto;
  6. }
  7. .virtual-box ul {
  8. padding: 0;
  9. margin: 0;
  10. list-style: none;
  11. }
  12. .virtual-box li {
  13. padding-left: 10px;
  14. border-bottom: 1px solid #333;
  15. }

设置初始位置

使用 jumpIndex 设置初始位置

VirtualList 虚拟滚动列表 - 图2

查看源码在线预览

  1. import { VirtualList } from '@alifd/next';
  2. const dataSource = [];
  3. function generateLi(index) {
  4. return (<li key={`key-${index}`} style={{lineHeight: '20px'}}>key-{index}</li>);
  5. }
  6. function generateData(len) {
  7. for (let i = 0; i < len; i++) {
  8. dataSource.push(generateLi(i));
  9. }
  10. }
  11. class App extends React.Component {
  12. state = {
  13. initial: 50,
  14. dataSource: generateData(1000)
  15. }
  16. onClick() {
  17. this.setState({
  18. initial: this.state.initial + 20
  19. });
  20. }
  21. render() {
  22. return (
  23. <div>
  24. <button onClick={this.onClick.bind(this)}>jump to {this.state.initial + 20}</button>
  25. <br/>
  26. <br/>
  27. <div className={'virtual-box'}>
  28. <VirtualList ref="virtual" jumpIndex={this.state.initial}>
  29. {dataSource}
  30. </VirtualList>
  31. </div>
  32. </div>
  33. );
  34. }
  35. }
  36. ReactDOM.render(<App />, mountNode);
  1. .virtual-box {
  2. height: 200px;
  3. width: 200px;
  4. border: 1px solid #ddd;
  5. overflow: auto;
  6. }
  7. .virtual-box ul {
  8. padding: 0;
  9. margin: 0;
  10. list-style: none;
  11. }
  12. .virtual-box li {
  13. padding-left: 10px;
  14. border-bottom: 1px solid #333;
  15. }

不等高的item

使用 jumpIndex 设置初始位置, 并设置 itemSizeGetter

VirtualList 虚拟滚动列表 - 图3

查看源码在线预览

  1. import { VirtualList } from '@alifd/next';
  2. const dataSource = [];
  3. function generateLi(index) {
  4. if (index % 3 === 0) {
  5. return (<li key={`key-${index}`} style={{lineHeight: '30px', background: '#5f83ff', color: '#fff'}}>key-{index}</li>);
  6. } else {
  7. return (<li key={`key-${index}`} style={{lineHeight: '20px'}}>key-{index}</li>);
  8. }
  9. }
  10. function generateData(len) {
  11. for (let i = 0; i < len; i++) {
  12. dataSource.push(generateLi(i));
  13. }
  14. }
  15. class App extends React.Component {
  16. state = {
  17. initial: 20,
  18. dataSource: generateData(1000)
  19. }
  20. componentDidMount() {
  21. setTimeout(() => {
  22. const instance = this.refs.virtual.getInstance();
  23. instance.scrollTo(50);
  24. }, 200);
  25. }
  26. getHeight(index) {
  27. return index % 3 === 0 ? 30 : 20;
  28. }
  29. onClick() {
  30. this.setState({
  31. initial: this.state.initial + 20
  32. });
  33. }
  34. render() {
  35. return (
  36. <div>
  37. <button onClick={this.onClick.bind(this)}>jump to {this.state.initial + 20}</button>
  38. <br/>
  39. <br/>
  40. <div className={'virtual-box'}>
  41. <VirtualList ref="virtual" jumpIndex={this.state.initial} itemSizeGetter={this.getHeight.bind(this)}>
  42. {dataSource}
  43. </VirtualList>
  44. </div>
  45. </div>
  46. );
  47. }
  48. }
  49. ReactDOM.render(<App />, mountNode);
  1. .virtual-box {
  2. height: 200px;
  3. width: 200px;
  4. border: 1px solid #ddd;
  5. overflow: auto;
  6. }
  7. .virtual-box ul {
  8. padding: 0;
  9. margin: 0;
  10. list-style: none;
  11. }
  12. .virtual-box li {
  13. padding-left: 10px;
  14. border-bottom: 1px solid #333;
  15. }

相关区块

VirtualList 虚拟滚动列表 - 图4

暂无相关区块