有效呈现大型列表和表格数据的React组件
JS当中直接操作DOM,会导致性能严重下降,
所以渲染长列表(也就是大量DOM),会导致浏览器卡顿严重,甚至有可能出现假死状态

https://bvaughn.github.io/react-virtualized/#/components/List
长列表文档 https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md

  1. yarn add react-virtualized
  1. import 'react-virtualized/styles.css';
  2. import {Column, Table} from 'react-virtualized';
  3. import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
  4. import List from 'react-virtualized/dist/commonjs/List';
  5. <List {...listProps} sortBy={sortBy} />

MultiGrid

  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import moment from 'moment';
  4. import {MultiGrid} from 'react-virtualized';
  5. import styles from "./MultiGrid/MultiGrid.example.css";
  6. import data from './_mockData'
  7. const subChild = () => {
  8. const arr = ['count', 'max']
  9. return arr.map(item => <div key={item} className='flex-1'>{item}</div>)
  10. }
  11. // 固定表头
  12. function getThead(columnIndex) {
  13. const { values } = data[0] || {};
  14. if(columnIndex < 2) {
  15. const arr = ['INFO', '机刷']
  16. return arr[columnIndex]
  17. };
  18. if(values) {
  19. const thead = values.map((item, i) => {
  20. const [time] = item;
  21. return moment(time).format('HH:mm');
  22. });
  23. return (
  24. <>
  25. <div style={{borderBottom: '1px solid #ddd'}}>{thead[columnIndex]}</div>
  26. <div className="flex">{subChild()}</div>
  27. </>
  28. );
  29. }
  30. }
  31. // 固定左侧的列
  32. function getColumns(columnIndex, rowIndex) {
  33. const {keys} = data[rowIndex-1];
  34. if(columnIndex > 1 ) return;
  35. return keys[columnIndex]
  36. }
  37. // 表格的内容
  38. function getTbody(columnIndex, rowIndex) {
  39. // rows
  40. const {values} = data[rowIndex-1];
  41. const columns = values[columnIndex - 2];
  42. console.log('getTbody', columnIndex, rowIndex, columns);
  43. return columns.map((item, i) => {
  44. console.log('item', item)
  45. if(i<3) return null
  46. return <div className='flex-1'>{item ? item : '-'}</div>
  47. });
  48. }
  49. function Index(props) {
  50. /**
  51. *
  52. * @param columnIndex
  53. * @param key 16-1
  54. * @param rowIndex
  55. * @param style {height: 40, left: 0, position: "absolute", top: 640, width: 75}
  56. * @returns {JSX.Element}
  57. */
  58. function cellRenderer({columnIndex, key, rowIndex, style}) {
  59. if(rowIndex === 0) {
  60. // const width = columnIndex < 2 ? 60 : style.width;
  61. console.log('style', style)
  62. return (
  63. <div className={styles.Cell} key={key} style={style}>
  64. {getThead(columnIndex)}
  65. </div>
  66. )
  67. }
  68. // 固定左侧2列
  69. if(columnIndex < 2) {
  70. return (
  71. <div className={styles.Cell} key={key} style={style}>
  72. {getColumns(columnIndex, rowIndex)}, {rowIndex}
  73. </div>
  74. );
  75. }
  76. // console.log('cell', columnIndex, rowIndex, 'key', key, style)
  77. return (
  78. <div className={styles.Cell} key={key} style={style}>
  79. <div className="flex">{getTbody(columnIndex, rowIndex)}</div>
  80. </div>
  81. );
  82. }
  83. return (
  84. <div style={{width: '80%'}}>
  85. <MultiGrid
  86. cellRenderer={cellRenderer} // 渲染的表格内容
  87. columnWidth={240} // 每列的宽度
  88. columnCount={182} // 多少列,如果有固定列,需要加上固定列
  89. fixedRowCount={1} // 固定的表头行
  90. fixedColumnCount={2} // 左侧固定的的列
  91. width={1200} // Table的宽度
  92. height={214} // Table的高度 + 滚动条的高度 14px
  93. styleTopRightGrid={{height: 80}}
  94. rowHeight={40} // 一行的高度
  95. rowCount={5} // 多少行
  96. hideTopRightGridScrollbar={true}
  97. />
  98. </div>
  99. );
  100. }
  101. export default Index;