有效呈现大型列表和表格数据的React组件
JS当中直接操作DOM,会导致性能严重下降,
所以渲染长列表(也就是大量DOM),会导致浏览器卡顿严重,甚至有可能出现假死状态
https://bvaughn.github.io/react-virtualized/#/components/List
长列表文档 https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md
yarn add react-virtualized
import 'react-virtualized/styles.css';
import {Column, Table} from 'react-virtualized';
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
import List from 'react-virtualized/dist/commonjs/List';
<List {...listProps} sortBy={sortBy} />
MultiGrid
import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import {MultiGrid} from 'react-virtualized';
import styles from "./MultiGrid/MultiGrid.example.css";
import data from './_mockData'
const subChild = () => {
const arr = ['count', 'max']
return arr.map(item => <div key={item} className='flex-1'>{item}</div>)
}
// 固定表头
function getThead(columnIndex) {
const { values } = data[0] || {};
if(columnIndex < 2) {
const arr = ['INFO', '机刷']
return arr[columnIndex]
};
if(values) {
const thead = values.map((item, i) => {
const [time] = item;
return moment(time).format('HH:mm');
});
return (
<>
<div style={{borderBottom: '1px solid #ddd'}}>{thead[columnIndex]}</div>
<div className="flex">{subChild()}</div>
</>
);
}
}
// 固定左侧的列
function getColumns(columnIndex, rowIndex) {
const {keys} = data[rowIndex-1];
if(columnIndex > 1 ) return;
return keys[columnIndex]
}
// 表格的内容
function getTbody(columnIndex, rowIndex) {
// rows
const {values} = data[rowIndex-1];
const columns = values[columnIndex - 2];
console.log('getTbody', columnIndex, rowIndex, columns);
return columns.map((item, i) => {
console.log('item', item)
if(i<3) return null
return <div className='flex-1'>{item ? item : '-'}</div>
});
}
function Index(props) {
/**
*
* @param columnIndex
* @param key 16-1
* @param rowIndex
* @param style {height: 40, left: 0, position: "absolute", top: 640, width: 75}
* @returns {JSX.Element}
*/
function cellRenderer({columnIndex, key, rowIndex, style}) {
if(rowIndex === 0) {
// const width = columnIndex < 2 ? 60 : style.width;
console.log('style', style)
return (
<div className={styles.Cell} key={key} style={style}>
{getThead(columnIndex)}
</div>
)
}
// 固定左侧2列
if(columnIndex < 2) {
return (
<div className={styles.Cell} key={key} style={style}>
{getColumns(columnIndex, rowIndex)}, {rowIndex}
</div>
);
}
// console.log('cell', columnIndex, rowIndex, 'key', key, style)
return (
<div className={styles.Cell} key={key} style={style}>
<div className="flex">{getTbody(columnIndex, rowIndex)}</div>
</div>
);
}
return (
<div style={{width: '80%'}}>
<MultiGrid
cellRenderer={cellRenderer} // 渲染的表格内容
columnWidth={240} // 每列的宽度
columnCount={182} // 多少列,如果有固定列,需要加上固定列
fixedRowCount={1} // 固定的表头行
fixedColumnCount={2} // 左侧固定的的列
width={1200} // Table的宽度
height={214} // Table的高度 + 滚动条的高度 14px
styleTopRightGrid={{height: 80}}
rowHeight={40} // 一行的高度
rowCount={5} // 多少行
hideTopRightGridScrollbar={true}
/>
</div>
);
}
export default Index;