React 中实现虚拟列表

直接上代码,代码里有注释!

react组件代码:

'use strict';

/**
 * 列表假数据 长度1000
 * */
const data = []
for (let i = 0;i< 1000; i++ ){
  data.push({
    key: i.toString(),
    val: 'Item' + i,
  })
}


class App extends React.Component{
  /*
  * 假设每项数据的dom元素高度为30px
  * 实际项目可能每项高度不一样
  * */
  static itemH = 30;

  constructor(props) {
    super(props);

    // 可视区域dom结构
    this.virtualList = React.createRef();

    // 计算总高度
    const totalH = data.length * App.itemH + 'px';

    this.state = {
      data: [], // 可视区域数据
      totalHeight: totalH, // 长列表总高度 列表中每一项数据高度总和
      transform:'',
    }


  }

  componentDidMount(){
    this.updateViewContent();
  }

  handleScroll = e => {
    /*
     * 获取scrollTop
     * 此属性可以获取或者设置对象的最顶部到对象在当前窗口显示的范围内的顶边的距离
     * 也就是元素滚动条被向下拉动的距离
     * */
    this.updateViewContent(e.target.scrollTop);
  };

  updateViewContent = (scrollTop = 0) => {
    // 计算可视区域里能放几个元素
    const viewCount = Math.ceil(this.virtualList.current.clientHeight/App.itemH);
    // 计算可视区域开始的索引
    const start = Math.floor(scrollTop/App.itemH);
    // 计算可视区域结束索引
    const end = start + viewCount;
    // 截取可视区域数据
    const viewData = data.slice(start,end);

    this.setState({
      data: viewData,

      // 把可见区域的 top 设置为起始元素在整个列表中的位置
      transform:`translate3d(0, ${ start * App.itemH }px, 0)`
    })
  };

  render(){
    const { totalHeight, transform, data } = this.state;

    return (
      <div className="virtual-list" onScroll={this.handleScroll} ref={this.virtualList}>
        <div className="virtual-list-height" style={{height: totalHeight}} />
        <div className="view-content" style={{transform: transform}}>
          {
            data.map(({key, val}) => (
              <div className="view-item" key={key}>{val}</div>
            ))
          }
        </div>
      </div>
    )
  }
}


ReactDOM.render(
  React.createElement(App),
  document.getElementById('app'),
)

CSS代码

.virtual-list{
	position: relative;
    height: 500px;
    overflow: auto;
    border: 1px solid #ddd;
}
.virtual-list-height {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    z-index: -1;
}

.view-content {
	position: absolute;
    left: 0;
    right: 0;
    top: 0;
}

.view-item {
    box-sizing: border-box;
    padding: 0 5px;
    height: 30px;
    line-height: 30px;
}
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Antd Table 是 Ant Design 框架的一个表格组件,而 react-window 则是一个能够帮助 React 应用高效渲染大量数据的组件。使用 react-window 能够减少因为渲染大量数据而导致页面卡顿的情况,提升用户的使用体验。 如果你希望在 Antd Table 使用 react-window 的虚拟列表功能,可以先安装 react-window: ``` npm install react-window ``` 然后,在 Antd Table 使用 react-window 的虚拟列表功能,需要进行如下操作: 1. 引入 react-window 库的 List 组件 2. 在 columns 配置项,设置 fixed 属性,以确保表头的列不会被虚拟化 3. 在 dataSource ,只保留当前可见区域的数据,而不是全部数据。 下面是一个 Antd Table 使用 react-window 的示例代码: ```jsx import { Table } from 'antd'; import { List } from 'react-window'; const VirtualTable = props => { const { columns, dataSource } = props; const renderRow = ({ index, style }) => { const rowData = dataSource[index]; return ( <div style={style}> <Table.Row key={rowData.key} record={rowData} index={index} columns={columns} /> </div> ); }; return ( <Table {...props} columns={columns.map(column => ({ ...column, fixed: column.fixed || 'left', }))} pagination={false} components={{ body: ({ children, ...restProps }) => { return ( <List height={400} itemCount={dataSource.length} itemSize={54} width={1000} {...restProps} > {renderRow} </List> ); }, }} /> ); }; export default VirtualTable; ``` 在上述代码,我们将 Antd Table 包装在一个名为 VirtualTable 的组件,该组件使用 react-window 的 List 组件来渲染表格数据。其,itemCount 和 itemSize 属性分别设置了数据总数和每一行的高度,height 和 width 属性则分别设置了表格的高度和宽度。在 renderRow 函数,我们根据当前的 index 和 style 来渲染每一行的数据。最后,我们将 List 组件作为 Antd Table 的 body 组件,以实现虚拟列表的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值