UNPKG

bee-table

Version:
1,250 lines (1,200 loc) 93.2 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import TableRow from './TableRow'; import TableHeader from './TableHeader'; import { measureScrollbar, debounce, warningOnce ,getMaxColChildrenLength } from './lib/utils'; import shallowequal from 'shallowequal'; import ColumnManager from './ColumnManager'; import createStore from './createStore'; import Loading from 'bee-loading'; import Icon from 'bee-icon'; import { Event,EventUtil,closest,myBrowser} from "./lib/utils"; import { arrayMoveTo } from "./lib/util"; import i18n from "./lib/i18n"; import { getComponentLocale } from "bee-locale/build/tool"; import ResizeObserver from 'resize-observer-polyfill'; import DragResizerLine from "./DragResizerLine"; import DragRowLine from "./DragRowLine"; const prefix = 'u'; const propTypes = { data: PropTypes.array, expandIconAsCell: PropTypes.bool, defaultExpandAllRows: PropTypes.bool, expandedRowKeys: PropTypes.array, defaultExpandedRowKeys: PropTypes.array, useFixedHeader: PropTypes.bool, columns: PropTypes.array, clsPrefix: PropTypes.string, bodyStyle: PropTypes.object, style: PropTypes.object, //特殊的渲染规则的key值 rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), rowClassName: PropTypes.func, //column的主键,和 column.key 作用相同 columnKey: PropTypes.string, expandedRowClassName: PropTypes.func, childrenColumnName: PropTypes.string, onExpand: PropTypes.func, onRowHover:PropTypes.func, onExpandedRowsChange: PropTypes.func, indentSize: PropTypes.number, onRowClick: PropTypes.func, onRowDoubleClick: PropTypes.func, expandIconColumnIndex: PropTypes.number, //是否显示表头 showHeader: PropTypes.bool, title: PropTypes.func, footer: PropTypes.func, emptyText: PropTypes.func, scroll: PropTypes.object, rowRef: PropTypes.func, getBodyWrapper: PropTypes.func, children: PropTypes.node, draggable: PropTypes.bool, minColumnWidth: PropTypes.number, filterable: PropTypes.bool, filterDelay: PropTypes.number, onFilterChange: PropTypes.func, onFilterClear: PropTypes.func, syncHover: PropTypes.bool, tabIndex:PropTypes.string, hoverContent:PropTypes.func, size: PropTypes.oneOf(['sm', 'md', 'lg']), rowDraggAble: PropTypes.bool, hideDragHandle: PropTypes.bool, // 隐藏行拖拽把手 onDropRow: PropTypes.func, onDragRowStart: PropTypes.func, onBodyScroll: PropTypes.func, bodyDisplayInRow: PropTypes.bool, // 表格内容超出列宽度时进行换行 or 以...形式展现 headerDisplayInRow: PropTypes.bool, // 表头内容超出列宽度时进行换行 or 以...形式展现 showRowNum: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), // 表格是否自动生成序号,格式为{base:number || 0,defaultKey:string || '_index',defaultName:string || '序号'} onPaste:PropTypes.func, onBodyMouseLeave: PropTypes.func, originWidth: PropTypes.number, scrollTop: PropTypes.number, lazyLoad: PropTypes.bool, ignoreScrollYChange: PropTypes.func, onResize: PropTypes.func, bordered: PropTypes.bool, onDragStart: PropTypes.func, onDragEnter: PropTypes.func, onDragOver: PropTypes.func, onDrop: PropTypes.func, onDragEnd: PropTypes.func, onMouseDown: PropTypes.func, onMouseMove: PropTypes.func, onMouseUp: PropTypes.func, dragborder: PropTypes.bool, onDropBorder: PropTypes.func, onDraggingBorder: PropTypes.func, dragborderKey: PropTypes.string, headerHeight: PropTypes.string, afterDragColWidth: PropTypes.number, headerScroll: PropTypes.func, headerEventNoStop: PropTypes.bool, onCopy: PropTypes.func, resetScroll: PropTypes.func, footerScroll: PropTypes.func, hideHeaderScroll: PropTypes.func, locale: PropTypes.string, getCellClassName: PropTypes.string, useDragHandle: PropTypes.func, expandedRowRender: PropTypes.any, expandRowByClick: PropTypes.func, haveExpandIcon: PropTypes.any, expandedIcon: PropTypes.any, collapsedIcon: PropTypes.any, height: PropTypes.number, showSum: PropTypes.bool, heightConsistent: PropTypes.bool, syncFixedRowHeight: PropTypes.bool, setRowHeight: PropTypes.func, setRowParentIndex: PropTypes.func, handleScrollY: PropTypes.func, handleScrollX: PropTypes.func, onKeyTab: PropTypes.func, onKeyUp: PropTypes.func, onKeyDown: PropTypes.func, onTableKeyDown: PropTypes.func, focusable: PropTypes.bool, loading: PropTypes.bool, }; const defaultProps = { data: [], useFixedHeader: true, expandIconAsCell: false, defaultExpandAllRows: false, defaultExpandedRowKeys: [], columnKey: 'key', rowKey: 'key', rowClassName: () => '', expandedRowClassName: () => '', onExpand() { }, onExpandedRowsChange() { }, onRowClick() { }, // onRowDoubleClick() { }, clsPrefix: prefix+'-table', bodyStyle: {}, style: {}, childrenColumnName: 'children', indentSize: 15, expandIconColumnIndex: 0, showHeader: true, scroll: {}, rowRef: () => null, getBodyWrapper: body => body, // emptyText: () => <div><Icon type="uf-nodata" className="table-nodata"></Icon><span>{locale["no_data"]}</span></div>, columns:[], minColumnWidth: 80, locale:{}, syncHover: true, // setRowHeight:()=>{}, setRowParentIndex:()=>{}, tabIndex:'0', heightConsistent:false, size: 'md', rowDraggAble:false, hideDragHandle:false, onDropRow: ()=>{}, onDragRowStart: ()=>{}, onBodyScroll: ()=>{}, bodyDisplayInRow: true, headerDisplayInRow: true, headerHeight:null, showRowNum: false, onPaste:()=>{}, originWidth:null//做什么用?? }; const expandIconCellWidth = Number(43); const tableUUID = ()=> "_table_uid_"+new Date().getTime() let browserInfo = {}; class Table extends Component { constructor(props) { super(props); browserInfo = myBrowser(); let expandedRowKeys = []; let rows = [...props.data]; const showDragHandle = !props.hideDragHandle && props.rowDraggAble; this.columnManager = new ColumnManager(props.columns, props.children, props.originWidth, showDragHandle, props.showRowNum); // 加入props.showRowNum参数 this.store = createStore({ currentHoverKey: null }); this.firstDid = true; this.scrollYChanged = false; if (props.defaultExpandAllRows) { for (let i = 0; i < rows.length; i++) { const row = rows[i]; expandedRowKeys.push(this.getRowKey(row, i)); rows = rows.concat(row[props.childrenColumnName] || []); } } else { expandedRowKeys = props.expandedRowKeys || props.defaultExpandedRowKeys; } this.state = { expandedRowKeys, data: props.data, currentHoverKey: null, scrollPosition: 'left', fixedColumnsHeadRowsHeight: null, fixedColumnsBodyRowsHeight: [], fixedColumnsExpandedRowsHeight: {}, //扩展行的高度 } this.onExpandedRowsChange = this.onExpandedRowsChange.bind(this); this.onExpanded = this.onExpanded.bind(this); this.onRowDestroy = this.onRowDestroy.bind(this); this.getRowKey = this.getRowKey.bind(this); this.getExpandedRows = this.getExpandedRows.bind(this); this.getHeader = this.getHeader.bind(this); this.getHeaderRows = this.getHeaderRows.bind(this); this.getExpandedRow = this.getExpandedRow.bind(this); this.getRowsByData = this.getRowsByData.bind(this); this.getRows = this.getRows.bind(this); this.getColGroup = this.getColGroup.bind(this); this.getLeftFixedTable = this.getLeftFixedTable.bind(this); this.getRightFixedTable = this.getRightFixedTable.bind(this); this.getTable = this.getTable.bind(this); this.getTitle = this.getTitle.bind(this); this.getFooter = this.getFooter.bind(this); this.getEmptyText = this.getEmptyText.bind(this); this.syncFixedTableRowHeight = this.syncFixedTableRowHeight.bind(this); this.resetScrollX = this.resetScrollX.bind(this); this.findExpandedRow = this.findExpandedRow.bind(this); this.isRowExpanded = this.isRowExpanded.bind(this); // this.detectScrollTarget = this.detectScrollTarget.bind(this); this.handleBodyScroll = this.handleBodyScroll.bind(this); this.handleRowHover = this.handleRowHover.bind(this); this.computeTableWidth = this.computeTableWidth.bind(this); this.onBodyMouseLeave = this.onBodyMouseLeave.bind(this); this.tableUid = tableUUID(); this.contentTable = null; this.leftColumnsLength //左侧固定列的长度 this.centerColumnsLength //非固定列的长度// this.columnsChildrenList = [];//复杂表头、所有叶子节点 this.dataChanged = false; // 数据是否改变 //同步行高时使用的缓存 this.fixedColumnsBodyRowsHeightCache = null; this.fixedColumnsExpandedRowsHeightCache = null; } componentWillMount() { this.centerColumnsLength = this.columnManager.centerColumns().length this.leftColumnsLength = this.columnManager.leftColumns().length } componentDidMount() { // this.getTableUID(); EventUtil.addHandler(this.contentTable,'keydown',this.onKeyDown); EventUtil.addHandler(this.contentTable,'focus',this.onFocus); setTimeout(this.resetScrollX, 300); //含有纵向滚动条 // if(this.props.scroll.y){ // this.scrollbarWidth = measureScrollbar(`.u-table`); // } this.scrollbarWidth = measureScrollbar(`.${this.props.clsPrefix}`);//dom装载后获取浏览器下的滚动条宽度 //后续也放在recevice里面 if (!this.props.originWidth) { this.computeTableWidth(); } let {useFixedHeader,scroll={}} = this.props; if (this.columnManager.isAnyColumnsFixed()) { this.syncFixedTableRowHeight();//同步固定列的内容行高度 const targetNode = this.contentTable if (targetNode) { this.resizeObserver = new ResizeObserver(() => { this.resize() }); this.resizeObserver.observe(targetNode) } } if(scroll.y){//固定列头存在则执行head和body的宽度 this.syncFixedTableScrollWidth();//同步固定列的滚动宽度 } } componentWillReceiveProps(nextProps) { let { hideDragHandle, rowDraggAble, showRowNum ,clsPrefix} = this.props; // 清除同步行高时使用的缓存 this.fixedColumnsBodyRowsHeightCache = null; this.fixedColumnsExpandedRowsHeightCache = null; if ('data' in nextProps) { this.setState({ data: nextProps.data, }); } if ('defaultExpandAllRows' in nextProps) { const { defaultExpandAllRows, data, expandedRowKeys, childrenColumnName = 'children'} = nextProps; if (defaultExpandAllRows && !expandedRowKeys) { let _expandedRowKeys = []; let rows = [...(data || [])]; for (let i = 0; i < rows.length; i++) { const row = rows[i]; _expandedRowKeys.push(this.getRowKey(row, i)); rows = rows.concat(row[childrenColumnName] || []); } this.setState({ expandedRowKeys: _expandedRowKeys }) } else if (!defaultExpandAllRows && !expandedRowKeys) { this.expandedRowKeys = [] } } if ('expandedRowKeys' in nextProps) { this.setState({ expandedRowKeys: nextProps.expandedRowKeys, }); } if (nextProps.columns && !shallowequal(nextProps.columns,this.props.columns)) { this.columnManager.reset(nextProps.columns, null, showRowNum, !hideDragHandle && rowDraggAble); // 加入this.props.showRowNum参数 if(nextProps.columns.length !== this.props.columns.length && this.bodyTable){ this.scrollTop = this.bodyTable.scrollTop; } } else if (nextProps.children !== this.props.children) { this.columnManager.reset(null, nextProps.children, showRowNum, !hideDragHandle && rowDraggAble); // 加入this.props.showRowNum参数 } //适配lazyload if(nextProps.scrollTop > -1){ // this.bodyTable.scrollTop = nextProps.scrollTop; this.scrollTop = nextProps.scrollTop; } // fix:模态框中使用table,计算的滚动条宽度为0的bug // fix:表格首次渲染时 display:none,再显示时,未重新计算,导致表行出现错位的bug // if(this.scrollbarWidth<=0 && this.props.scroll.y){ // this.scrollbarWidth = measureScrollbar(`.${clsPrefix}`); // } if (!nextProps.originWidth) { this.computeTableWidth(); this.firstDid = true;//避免重复update } if(nextProps.resetScroll){ this.resetScrollX(); } // console.log('this.scrollTop**********',this.scrollTop); } componentDidUpdate(prevProps, prevState) { // todo: IE 大数据渲染,行高不固定,且设置了 heightConsistent={true} 时,滚动加载操作会导致 ie11 浏览器崩溃 // https://github.com/tinper-bee/bee-table/commit/bd2092cdbaad236ff89477304e58dea93325bf09 let {useFixedHeader,scroll = {}} = this.props; if(this.columnManager.isAnyColumnsFixed()) { debounce(this.syncFixedTableRowHeight(),200);//同步固定列内容行的高度 } if(scroll.y){//固定列头存在则执行head和body的宽度 debounce(this.syncFixedTableScrollWidth(),200);//同步固定列的滚动宽度 } //适应模态框中表格、以及父容器宽度变化的情况 if (typeof (this.props.scroll.x) !== 'number' && this.contentTable.getBoundingClientRect().width !== this.contentDomWidth && this.firstDid) { this.computeTableWidth(); this.firstDid = false;//避免重复update } if(this.scrollTop > -1){ this.fixedLeftBodyInner && ( this.fixedLeftBodyInner.scrollTop = this.scrollTop); this.fixedRightBodyInner && ( this.fixedRightBodyInner.scrollTop = this.scrollTop); this.bodyTable.scrollTop = this.scrollTop; this.scrollTop = -1; } // 当表格没有数据时,重置滚动条位置,造成grid里面的表头列无法操作 // if (prevProps.data.length === 0 || this.props.data.length === 0 ) { // this.resetScrollX(); // } // 当懒加载手动设置的scroll.y发生变化时,滚动条回到顶部 const prevScrollY = prevProps.scroll.y const currentScrollY = this.props.scroll.y if (prevScrollY && currentScrollY && (prevScrollY !== currentScrollY) && this.props.lazyLoad && !this.props.ignoreScrollYChange) { this.bodyTable.scrollTop = 0 } else if (this.props.ignoreScrollYChange && currentScrollY && prevScrollY) { if (prevScrollY !== currentScrollY) { this.scrollYChanged = true const bodyScrollTop = this.bodyTable.scrollTop if (bodyScrollTop === 0) { // 在顶部的时候,滚动条不用动 this.bodyTable.scrollTop = 0; } else { const distance = bodyScrollTop + currentScrollY - prevScrollY; if (distance < 0) { this.bodyTable.scrollTop = 0; } else { const { scrollHeight, scrollTop } = this.bodyTable const bottomDistance = Math.abs(scrollHeight - scrollTop - prevScrollY) // 在最底部的时候也不用滚动滚动条 if (bottomDistance < 5) { // 有些dom计算不是十分精确,设置一个值来缓冲一下 this.bodyTable.scrollTop = scrollTop + prevScrollY - currentScrollY } else { this.bodyTable.scrollTop = distance; } } } } else if (this.scrollYChanged) { this.bodyTable.scrollTop += 1 this.scrollYChanged = false } } // 是否传入 scroll中的y属性,如果传入判断是否是整数,如果是则进行比较 。bodyTable 的clientHeight进行判断 // this.isShowScrollY(); // gx为了解决底部滚动条显示的问题 // if (this.bodyTable) { // const currentOverflowX = window.getComputedStyle(this.bodyTable).overflowX; // if (this.props.scroll.x && currentOverflowX !== 'scroll') { // // 此处应该对比一下实际的 // if (this.computeWidth > this.contentDomWidth) { // this.bodyTable.style.overflowX = 'scroll'; // } // } // } // let scrollContainerWidth = window.getComputedStyle(this.bodyTableOuter.querySelector('.scroll-container')).width; // scroll-container层元素的宽度 // let scrollContainerTableWidth = this.bodyTableOuter.querySelector('.table-bordered').style.width; // scroll-container内层table元素的宽度 // // 有左右固定列时,scroll-container因为有竖直滚动条,使得scroll-container实际宽度(不包括滚动条的宽度)小于内部table宽度出现水平方向滚动条,导致滚动到底部不对齐 // if ((parseFloat(scrollContainerWidth) >= parseFloat(scrollContainerTableWidth)) && (this.columnManager.leftLeafColumns().length > 0 || this.columnManager.rightLeafColumns().length > 0)) { // this.bodyTable.style.overflowX = 'hidden'; // } else { // this.bodyTable.style.overflowX = 'auto'; // } // if (this.bodyTableOuter) { // 隐藏几个不需要真正滚动的父元素的滚动条 // this.bodyTableOuter.style.overflowY = 'hidden' // } // if (this.fixedColumnsBodyLeftOuter) { // this.fixedColumnsBodyLeftOuter.style.overflowY = 'hidden' // } // if (this.fixedColumnsBodyRightOuter) { // this.fixedColumnsBodyRightOuter.style.overflowY = 'hidden' // } } componentWillUnmount() { // 移除绑定事件,避免内存泄漏 this.contentTable = null; EventUtil.removeHandler(this.contentTable,'keydown',this.onKeyDown); EventUtil.removeHandler(this.contentTable,'focus',this.onFocus); if (this.resizeObserver) { this.resizeObserver.disconnect() } } resize = ()=>{ let debounceFunc = ()=>{ this.syncFixedTableRowHeight(); this.computeTableWidth(); typeof this.props.onResize =='function' && this.props.onResize(); }; debounce(debounceFunc(), 150); let renderFlag = this.state.renderFlag; this.setState({ renderFlag: !renderFlag }); } /* getTableUID =()=>{ let uid = "_table_uid_"+new Date().getTime(); this.tableUid = uid; let div = document.createElement("div"); div.className = "u-table-drag-hidden-cont"; div.id = uid; this.contentTable.appendChild(div); } */ //计算表格宽度 --- 这块有必要?待确认 待废除 zzj computeTableWidth() { let {expandIconAsCell} = this.props; //如果用户传了scroll.x按用户传的为主 let setWidthParam = this.props.scroll.x if (typeof (setWidthParam) == 'number') { let numSetWidthParam = parseInt(setWidthParam); this.contentWidth = numSetWidthParam; } else { // this.preContentDomWidth = this.contentDomWidth; //计算总表格宽度、根据表格宽度和各列的宽度和比较,重置最后一列 this.contentDomWidth = this.contentTable.getBoundingClientRect().width//表格容器宽度 this.contentWidth = this.contentDomWidth;//默认与容器宽度一样 } const computeObj = this.columnManager.getColumnWidth(this.contentWidth); const expandColWidth = expandIconAsCell ? expandIconCellWidth : 0; let lastShowIndex = computeObj.lastShowIndex; this.computeWidth = computeObj.computeWidth + expandColWidth; this.domWidthDiff = this.contentDomWidth - this.computeWidth; if (typeof (setWidthParam) == 'string' && setWidthParam.indexOf('%')) { this.contentWidth = this.contentWidth * parseInt(setWidthParam) / 100; this.domWidthDiff = this.contentDomWidth - this.contentWidth; } if (this.computeWidth < this.contentWidth) { let contentWidthDiff = this.scrollbarWidth?this.contentWidth - this.computeWidth-this.scrollbarWidth:this.contentWidth - this.computeWidth; //bordered的表格需要减去边框的差值1 if(this.props.bordered){ contentWidthDiff = contentWidthDiff-1; } this.setState({ contentWidthDiff, lastShowIndex }); } else { this.contentWidth = this.computeWidth; this.setState({ contentWidthDiff: 0, lastShowIndex });//重新渲染,为了显示滚动条 } } /* //根据内容动态的判断是否显示纵向滚动条 isShowScrollY(){ const props = this.props; const y = props.scroll && props.scroll.y; if(y){ const bodyH = this.bodyTable.clientHeight; const bodyContentH = this.bodyTable.querySelector('table').clientHeight; const rightBodyTable = this.fixedRightBodyInner; // const leftBodyTable = this.fixedLeftBodyInner; const overflowy = bodyContentH <= bodyH ? 'auto':'scroll'; this.bodyTable.style.overflowY = overflowy; this.headTable.style.overflowY = overflowy; rightBodyTable && (rightBodyTable.style.overflowY = overflowy); } } */ //同步固定列情况下部分区域滚动条出现引起的错位问题 syncFixedTableScrollWidth = ()=>{ const {clsPrefix} = this.props; let tableDom = this.contentTable; let tableContentDom = tableDom.querySelector(`.${clsPrefix}-content`); let tableFixedRight = tableDom.querySelector(`.${clsPrefix}-fixed-right`); let centerBodyDom = tableDom.querySelector(`.${clsPrefix}-scroll .${clsPrefix}-body`); let centerHeadDom = tableDom.querySelector(`.${clsPrefix}-scroll .${clsPrefix}-header`);//固定列头的情况下 if(!centerHeadDom)centerHeadDom = tableDom.querySelector(`.${clsPrefix}-scroll .${clsPrefix}-thead`);//未固定列头的情况下 //注意精准匹配,以确保行展开表格嵌套表格时正确匹配 let centerHeadTableDom = tableDom.querySelector(`.${clsPrefix}-scroll .${clsPrefix}-header > table[data-for-table='${this.tableUid}']`); let centerBodyTableDom = tableDom.querySelector(`.${clsPrefix}-scroll .${clsPrefix}-body > table[data-for-table='${this.tableUid}']`); let bodyInnerDoms = tableDom.querySelectorAll(`.${clsPrefix}-body-outer .${clsPrefix}-body-inner`); // if(!this.scrollbarWidth)this.scrollbarWidth=measureScrollbar(); let scrollbarWidth = this.scrollbarWidth; let hasCenterScrollY = centerBodyTableDom.getBoundingClientRect().height>centerBodyDom.getBoundingClientRect().height?true:false;//中间区域是否存在垂直滚动条 // let hasCenterScrollX = centerBodyTableDom.getBoundingClientRect().width>centerBodyDom.getBoundingClientRect().width?true:false;//中间区域存在水平滚动条 let hasCenterScrollX = centerBodyDom.scrollWidth>(centerBodyDom.clientWidth+1)?true:false;//中间区域存在水平滚动条 //console.log("AAA---->syncFixedTableScrollWidth-->hasCenterScrollX"+hasCenterScrollX+"-->hasCenterScrollY"+hasCenterScrollY+"--->scrollbarWidth"+scrollbarWidth) //解决存在右侧固定列,中间区域垂直滚动条需要隐藏显示的问题 if(hasCenterScrollY&&this.columnManager.isAnyColumnsRightFixed()){ //非Chrome内核浏览器中间区域会出现多余垂直滚动条需要隐藏 if(browserInfo.browserType=='Chrome'){ centerBodyDom.style.marginRight = 0; }else{ centerBodyDom.style.marginRight = (-scrollbarWidth)+"px"; } if(browserInfo.osType=='Mac'&&browserInfo.browserType=='FF'){//解决mac的ff下右侧固定列存在,中间区域右侧被遮挡的问题 centerBodyTableDom.style.paddingRight = scrollbarWidth+"px"; } }else{ centerBodyDom.style.marginRight = 0; } if(centerHeadDom)centerHeadDom.style.marginRight = centerBodyDom.style.marginRight; //解决中间区域存在水平滚动条,左右固定区域无法跟其对齐的问题 if(bodyInnerDoms&&bodyInnerDoms.length){ [].forEach.call(bodyInnerDoms,(bodyInnerDom)=>{ if(hasCenterScrollX) { if(browserInfo.browserType=='Chrome'){//mac下验证 if(hasCenterScrollX){ bodyInnerDom.style.overflowX = 'scroll'; }else{ bodyInnerDom.style.overflowX = 'hidden'; } }else{ if(browserInfo.osType=='Win'&&browserInfo.browserType=='FF') { bodyInnerDom.style.overflowX = 'hidden';//win的firefox下,中间x滚动出现时,左右固定列x滚动条隐藏通过paddingBottom填充占位 }else{ bodyInnerDom.style.overflowX = 'scroll';//确保中间x滚动出现时,左右固定列x滚动条正确显示占位 } } // bodyInnerDom.style.paddingBottom = browserInfo.browserType=='Chrome'?0:`${scrollbarWidth}px`;//chrome下左右固定列底部不需要填充占位,firefox需要占位, if(browserInfo.osType=='Win'&&browserInfo.browserType=='FF'){ bodyInnerDom.style.paddingBottom = `${scrollbarWidth}px`;//win的firefox不需显示x滚动条但需要填充占位 }else{ bodyInnerDom.style.paddingBottom = 0;//firefox升级89.0.2后不需要占位了 } }else { bodyInnerDom.style.overflowX = 'hidden';//确保中间x滚动不出现时,左右固定列x滚动条不显示 bodyInnerDom.style.paddingBottom = 0; } }); } //解决中间存在水平滚动条头部区域无法对齐的问题 if(centerHeadTableDom){ let paddingWidth = 0; if(hasCenterScrollY && hasCenterScrollX || hasCenterScrollY && !tableFixedRight)paddingWidth=paddingWidth+scrollbarWidth; centerHeadTableDom.style.paddingRight=`${paddingWidth}px`; } //为表格追加是否存在滚动条的样式标识 if(tableContentDom){ if(hasCenterScrollX){ if(!tableContentDom.classList.contains('has-scroll-x'))tableContentDom.classList.add('has-scroll-x'); }else{ tableContentDom.classList.remove('has-scroll-x'); } if(hasCenterScrollY){ if(!tableContentDom.classList.contains('has-scroll-y'))tableContentDom.classList.add('has-scroll-y'); }else{ tableContentDom.classList.remove('has-scroll-y'); } //中间区域有垂直滚动条 if(hasCenterScrollY){ if(this.headTable){//中间区域有垂直滚动条,则头部也需要显示头部滚动条 this.headTable.style.overflowY='scroll'; if(this.columnManager.isAnyColumnsRightFixed()){ //右侧固定列存在时需要头部Y滚动条占位 }else{ if(browserInfo.osType=='Win'&&browserInfo.browserType=='FF'){ // 解决win下FF的头部右上角多于滚动条显示问题 this.headTable.style.overflowY='hidden'; this.headTable.style.paddingRight = `${scrollbarWidth}px`; } } } }else{ if(this.headTable)this.headTable.style.overflowY='hidden';//中间区域无垂直滚动条,则头部也不需要显示头部滚动条 } } } onExpandedRowsChange(expandedRowKeys) { if (!this.props.expandedRowKeys) { this.setState({ expandedRowKeys }); } this.props.onExpandedRowsChange(expandedRowKeys); } onExpanded(expanded, record, index, e) { if (e) { e.preventDefault(); e.stopPropagation(); } const info = this.findExpandedRow(record); if (typeof info !== 'undefined' && !expanded) { this.onRowDestroy(record, index, true); } else if (!info && expanded) { const expandedRows = this.getExpandedRows().concat(); expandedRows.push(this.getRowKey(record, index)); this.onExpandedRowsChange(expandedRows); } this.props.onExpand(expanded, record,index); } onRowDestroy(record, rowIndex, isExpandOperation) { const expandedRows = this.getExpandedRows().concat(); const rowKey = this.getRowKey(record, rowIndex); let index = -1; expandedRows.forEach((r, i) => { if (r === rowKey) { index = i; } }); if (index !== -1) { expandedRows.splice(index, 1); } // if(this.currentHoverKey == rowKey && this.hoverDom){ this.hoverDom.style.display = 'none'; } // todo:如果是TableRow组件卸载触发的该方法,需要加判断,解决懒加载时,持续触发onExpandedRowsChange的问题 if(isExpandOperation){ this.onExpandedRowsChange(expandedRows); } else { const info = this.findExpandedRow(record); if(typeof info === 'undefined'){ this.onExpandedRowsChange(expandedRows); } } } getRowKey(record, index) { const rowKey = this.props.rowKey; const key = (typeof rowKey === 'function') ? rowKey(record, index) : record[rowKey]; warningOnce( key !== undefined, 'Each record in table should have a unique `key` prop,' + 'or set `rowKey` to an unique primary key.' ); return key; } getExpandedRows() { return this.props.expandedRowKeys || this.state.expandedRowKeys; } getHeader(columns, fixed, leftFixedWidth, rightFixedWidth) { const { filterDelay, onFilterChange, onFilterClear, filterable, showHeader, expandIconAsCell, clsPrefix, onDragStart, onDragEnter, onDragOver, onDrop,onDragEnd, draggable, onMouseDown, onMouseMove, onMouseUp, dragborder, dragborderKey, minColumnWidth, headerHeight,afterDragColWidth,headerScroll ,bordered,onDropBorder,onDraggingBorder, bodyDisplayInRow, headerEventNoStop, onCopy} = this.props; let columnsChildrenList = []; //复杂表头拖拽,重新render表头前,将其置空 const rows = this.getHeaderRows({columns,columnsChildrenList}); if (expandIconAsCell) { let hasLeftFixed = this.columnManager.isAnyColumnsLeftFixed(); if((hasLeftFixed && fixed =='left') //存在左侧固定列则展开图标独立到左侧区域 ||(!hasLeftFixed && !fixed) //不存在左侧固定列则展开图标独立到中间区域 ){ rows[0].unshift({ key: `${prefix}-table-expandIconAsCell`, className: `${clsPrefix}-expand-icon-th`, title: '', rowSpan: rows.length, width: expandIconCellWidth }); columnsChildrenList.unshift({ className: `${prefix}-table-expand-icon-column`, key: "expand-icon" }) } } if(fixed){ columnsChildrenList = columnsChildrenList.filter((col)=>col.fixed==fixed);//只获取对应的固定列 }else{ columnsChildrenList = columnsChildrenList.filter((col)=>!col.fixed);//只获取非固定的列 } // const trStyle = headerHeight&&!fixed ? { height: headerHeight } : (fixed ? this.getHeaderRowStyle(columns, rows) : null); const trStyle = this.getHeaderRowStyle(columns, rows);//确保固定列和非固定列表头行高一致 let drop = draggable ? { onDragStart, onDragOver, onDrop,onDragEnd, onDragEnter, draggable } : {}; let dragBorder = dragborder ? { onMouseDown:this.onDragBorderMouseDown, onMouseMove, onMouseUp, dragborder, dragborderKey,onDropBorder,onDraggingBorder } : {}; return showHeader ? ( <TableHeader {...drop} {...dragBorder} columnManager={this.columnManager} columnsChildrenList={columnsChildrenList} locale={this.props.locale} minColumnWidth={minColumnWidth} contentWidthDiff={!fixed?this.state.contentWidthDiff:0} // contentWidth={this.contentWidth} clsPrefix={clsPrefix} rows={rows} contentTable={this.contentTable} rowStyle={trStyle} fixed={fixed} filterable={filterable} onFilterChange={onFilterChange} onFilterClear={onFilterClear} filterDelay={filterDelay} afterDragColWidth = {afterDragColWidth} contentDomWidth={this.contentDomWidth} scrollbarWidth = {this.scrollbarWidth} headerScroll = {headerScroll} bordered = {bordered} tableUid = {this.tableUid} leftFixedWidth = {leftFixedWidth} rightFixedWidth = {rightFixedWidth} bodyDisplayInRow = {bodyDisplayInRow} eventNoStop = {headerEventNoStop} onCopy = {onCopy} /> ) : null; } getHeaderRows(options) { let {columns, currentRow = 0, rows,columnsChildrenList} = options; const { columnKey } = this.props; // let { contentWidthDiff = 0, lastShowIndex = -1 } = this.state; let filterCol = []; rows = rows || []; rows[currentRow] = rows[currentRow] || []; // let centerShowColCount = 0; columns.forEach((column,i) => { if (!column.key) { column.key = column[columnKey]; } if (column.rowSpan && rows.length < column.rowSpan) { while (rows.length < column.rowSpan) { rows.push([]); } } let width = column.width; if (typeof (width) == 'string' && width.indexOf('%') > -1 && this.contentWidth) { width = Math.ceil(this.contentWidth * parseInt(width) / 100); } else if (width) { width = parseInt(width); } // if (!column.fixed && column.ifshow) { // centerShowColCount++;//非固定列显示的个数 // if(lastShowIndex+1 == centerShowColCount && width){//对最后一列进行补全宽度 // width = width + contentWidthDiff; // } // } const cell = { key: column.key, className: column.className || '', children: column.title, drgHover: column.drgHover, fixed: column.fixed, width: width, dataIndex:column.dataIndex, textAlign:column.textAlign, titleAlign: column.titleAlign, // 标题水平对齐方式 required: column.required, // 标题是否展示必填标志 dragborder: column.dragborder || '', // 禁止某列拖动 }; if (column.onHeadCellClick) { cell.onClick = column.onHeadCellClick; } if (column.children) { this.getHeaderRows({columns:column.children,currentRow: currentRow + 1, rows,columnsChildrenList}); } else { columnsChildrenList&&columnsChildrenList.push(column); //复杂表头拖拽,所有叶子节点 } if ('colSpan' in column) { cell.colSpan = column.colSpan; } if ('rowSpan' in column) { cell.rowSpan = column.rowSpan; } if (cell.colSpan !== 0) { rows[currentRow].push(cell); } //判断是否启用过滤 if (this.props.filterable) { //组装Filter需要的Col filterCol.push({ key: column.key, children: "过滤渲染", width: column.width, fixed: column.fixed, // fixed filtertype: column.filterType,//下拉的类型 包括['text','dropdown','date','daterange','number'] dataIndex: column.dataIndex,//field datasource: this.props.data,//需要单独拿到数据处理 format: column.format,//设置日期的格式 filterdropdown: column.filterDropdown,//是否显示 show hide filterdropdownauto: column.filterDropdownAuto,//是否自定义数据 filterdropdowndata: column.filterDropdownData,//自定义数据格式 filterdropdownfocus: column.filterDropdownFocus,//焦点触发函数回调 filterdropdowntype: column.filterDropdownType,//下拉的类型分为 String,Number 默认是String filterdropdownincludekeys: column.filterDropdownIncludeKeys,//下拉条件按照指定的keys去显示 filterinputnumberoptions: column.filterInputNumberOptions//设置数值框内的详细属性 }); } }); if (this.props.filterable) { rows.push(filterCol); } return rows.filter(row => row.length > 0); } getExpandedRow(key, content, visible, className, fixed, record, index) { const { clsPrefix, expandIconAsCell,onPaste, getCellClassName } = this.props; let colCount; if (fixed === 'left') { colCount = this.columnManager.leftLeafColumns().length; } else if (fixed === 'right') { colCount = this.columnManager.rightLeafColumns().length; } else { colCount = this.columnManager.centerColumns().length; //计算非固定列的个数,fix: 嵌套表格场景,右侧列断开的问题 } let hasLeftFixed = this.columnManager.isAnyColumnsLeftFixed(); let expandedRowHeight = this.state.fixedColumnsExpandedRowsHeight[key] || 'auto'; function contentContainer() { if (content && content.props && content.props.style) { return ( <div style={{ height: content.props.style.height }}></div> ) } else { return ' ' } } const columns = [{ key: 'extra-row', render: () => ({ props: { colSpan: colCount, }, children: !fixed ? content : contentContainer(), }), }]; if (expandIconAsCell) { if((hasLeftFixed && fixed=='left') ||(!hasLeftFixed&&!fixed)){ columns.unshift({ key: 'expand-icon-placeholder', className:'expand-icon-placeholder', render: () => null, }); } } return ( <TableRow record={record} index={index} tableUid = {this.tableUid} onPaste={onPaste} columns={columns} visible={visible} className={className} key={`${key}-extra-row`} hoverKey={key} clsPrefix={`${clsPrefix}-expanded-row`} indent={1} expandIconAsCell={false} expandable={false} store={this.store} dragborderKey={this.props.dragborderKey} rowDraggAble={this.props.rowDraggAble} useDragHandle={this.props.useDragHandle} height={expandedRowHeight} getCellClassName = {getCellClassName} setRowHeight={this.props.setRowHeight} isExpandedRow={true} /> ); } //列宽度拖拽-鼠标按下的事件 onDragBorderMouseDown = (event)=>{ const {minColumnWidth} = this.props; let dragGapDom = Event.getTarget(event); let currentDom = dragGapDom.parentElement; let columnKey = currentDom.getAttribute('data-col-key'); let columnFixed = currentDom.getAttribute('data-th-fixed'); let columnWidth = currentDom.getAttribute('data-th-width'); let columnIndex = currentDom.getAttribute('data-col-index'); let currentInfo = {columnKey,columnFixed,columnWidth,columnIndex}; let tableRect = this.contentTable.getBoundingClientRect();//表格 let dragGapRect = dragGapDom.getBoundingClientRect();//当前的伸缩label //向上查找th元素 function getParentThElement(element){ let _tagName = element.tagName.toLowerCase(); if(element.getAttribute('data-filter-type') === 'filterContext')return null; if(_tagName === 'i')return null; if(_tagName != 'th'){ return getParentThElement(element.parentElement); }else{ return element; } } let thDom = getParentThElement(currentDom); let resizerDefaultWidth = thDom.getBoundingClientRect().width; let resizerLineHeight = tableRect.height; let resizerLineLeft = dragGapRect.right-tableRect.left-parseInt(dragGapRect.width/2)-1; let column = this.columnManager.leafColumns().find((col)=>col.key?col.key==columnKey:col.dataIndex==columnKey); this.setState({ resizerVisible: true, resizerLineHeight, resizerLineLeft, resizerDefaultWidth, resizerMinWidth:column.minWidth||minColumnWidth, dataSource: currentInfo, }); this.resizerLine.start(event); } //列宽度拖拽-鼠标松开的事件 onDragBorderMouseUp=(event,moveX, info)=> { const {minColumnWidth,onDropBorder} = this.props; let target = Event.getTarget(event); let {columnKey,columnFixed,columnWidth,columnIndex} = info; let column = this.columnManager.leafColumns().find((col)=>col.key?col.key==columnKey:col.dataIndex==columnKey); let oldWidth = ColumnManager.DefaultColumnWidth; //原宽度 if (typeof (column.width) == 'string' && column.width.indexOf('%') > -1 ) {//百分比情况 oldWidth = parseInt(columnWidth); }else if(column.width){//非百分比情况 oldWidth = parseInt(column.width); } let newWidth = oldWidth+moveX;//拖动后的宽度 newWidth = newWidth<minColumnWidth?minColumnWidth:newWidth;//限制最小宽度 this.columnManager.clearCache();//注意:先清除缓存 let changeColumn = this.columnManager.findColumn(column.key||column.dataIndex); if(!changeColumn){ console.error('拖拽列宽度未找到列定义:'+(column.key||column.dataIndex),column); return; } changeColumn.width = newWidth; this.computeTableWidth();//注意:重新计算需要补充的列宽度 // let newWidthDiff = newWidth-oldWidth;//计算新旧宽度的实际变化距离, 负数为缩小,正数为放大 // console.log("AAA---onDragBorderMouseUp-->最终距离"+moveX+'---表宽度--'+this.contentWidth+'---实际变化距离---'+newWidthDiff,this.columnManager.columns) this.setState({ resizerVisible: false, fixedColumnsHeadRowsHeight: null, fixedColumnsBodyRowsHeight: [], fixedColumnsExpandedRowsHeight: {}, // 扩展行的高度 }); typeof onDropBorder=='function' && onDropBorder(event, newWidth,column,this.columnManager.columns); } //列宽度拖拽-取消事件 onDragBorderCancel = (event,moveX,info)=>{ this.setState({ resizerVisible: false}); } //列宽度拖拽-鼠标移动的事件 onDragBorderMouseMove = (event,moveX,info)=>{ const {minColumnWidth,onDraggingBorder} = this.props; let {columnKey,columnFixed,columnWidth,columnIndex} = info; let column = this.columnManager.leafColumns().find((col)=>col.key?col.key==columnKey:col.dataIndex==columnKey); let oldWidth = ColumnManager.DefaultColumnWidth;//原宽度 //原宽度 if (typeof (column.width) == 'string' && column.width.indexOf('%') > -1 ) {//百分比情况 oldWidth = parseInt(columnWidth); }else if(column.width){//非百分比情况 oldWidth = parseInt(column.width); } let newWidth = oldWidth+moveX;//拖动后的宽度 newWidth = newWidth<minColumnWidth?minColumnWidth:newWidth;//限制最小宽度 typeof onDraggingBorder=='function' && onDraggingBorder(event, newWidth,column,this.columnManager.columns); // console.log("AAA---onDragBorderMouseMove-->移动距离"+moveX) } /** * 行拖拽开始时触发 * @param currentKey 当前拖拽目标的key */ _onRowDragStart = (options) => { let {dragStartKey} = options; let {lazyLoad,onRowDragStart} = this.props; if(lazyLoad){ onRowDragStart && onRowDragStart(options);//直接传递给bigDataX触发 }else{ let {data} = this.state,currentIndex,record; data.forEach((da,i)=>{ // tr 的唯一标识通过 data.key 或 rowKey 两种方式传进来 let trKey = da.key ? da.key : this.getRowKey(da, i); if(trKey == dragStartKey){ currentIndex = i; record = da; } }); this.props.onDragRowStart && this.props.onDragRowStart(record,currentIndex); } } /** * 行拖拽结束时触发 */ _onRowDragDrop = (options)=>{ let {lazyLoad,onRowDragDrop} = this.props; if(lazyLoad){ onRowDragDrop && onRowDragDrop(options);//直接传递给bigDataX触发 }else{ let {dragTargetKey,dragTargetIndex,dropTargetKey,dropTargetIndex} = options; let {data} = this.state,record; for(let i=0;i<data.length;i++){ let da = data[i]; // tr 的唯一标识通过 data.key 或 rowKey 两种方式传进来 let trKey = da.key ? da.key : this.getRowKey(da, i); if(trKey == dragTargetKey){ record = da;break; //匹配到后则退出减少性能开销 } } if (dragTargetIndex > -1) { data = arrayMoveTo(data,dragTargetIndex,dropTargetIndex); this.props.onDropRow && this.props.onDropRow(data,record,dropTargetIndex); this.setState({data}); } else { this.props.onDropRow && this.props.onDropRow(data,record,dropTargetIndex); } } // console.log("AAAA---->行拖拽结束:"+currentKey,targetKey); } /** * * * @param {*} data * @param {*} visible * @param {*} indent 层级 * @param {*} columns * @param {*} fixed * @param {number} [rootIndex=-1] 祖级节点 * @returns * @memberof Table */ getRowsByData(data, visible, indent, columns, fixed,rootIndex=-1) { const props = this.props; const childrenColumnName = props.childrenColumnName; const expandedRowRender = props.expandedRowRender; const expandRowByClick = props.expandRowByClick; const onPaste = props.onPaste; const anyColumnsFixed = this.columnManager.isAnyColumnsFixed(); const hasLeftFixed = this.columnManager.isAnyColumnsLeftFixed(); const { fixedColumnsBodyRowsHeight } = this.state; let rst = []; let height; const rowClassName = props.rowClassName; const rowRef = props.rowRef; const expandedRowClassName = props.expandedRowClassName; const needIndentSpaced = props.data.some(record => record[childrenColumnName]); const onRowClick = props.onRowClick; const onRowDoubleClick = props.onRowDoubleClick; //const expandIconAsCell = fixed !== 'right' ? props.expandIconAsCell : false; const expandIconColumnIndex = props.expandIconColumnIndex if(props.lazyLoad && props.lazyLoad.preHeight && indent == 0){ // console.log("AAA--->lazyLoad--first->"+props.lazyLoad.preHeight); rst.push( <TableRow onPaste={onPaste} height={props.lazyLoad.preHeight} columns={[]} className='table_lazyload_row_first' key={'table_lazyload_row_first'} store={this.store} visible = {true}/> ) } let leafColumns; if (fixed === 'left') { leafColumns = this.columnManager.leftLeafColumns(); } else if (fixed === 'right') { leafColumns = this.columnManager.rightLeafColumns(); } else { leafColumns = this.columnManager.leafColumns(); } const lazyCurrentIndex = props.lazyLoad && props.lazyLoad.startIndex ?props.lazyLoad.startIndex :0; const lazyParentIndex = props.lazyLoad && props.lazyLoad.startParentIndex ?props.lazyLoad.startParentIndex :0; const lazyEndIndex = props.lazyLoad && props.lazyLoad.endIndex ?props.lazyLoad.endIndex :-1; const lazyLoadEnable = (props.lazyLoad && props.lazyLoad.startIndex>-1 && props.lazyLoad.endIndex >-1); for (let i = 0; i < data.length; i++) { let isHiddenExpandIcon; const record = data[i]; const key = this.getRowKey(record, i); // 兼容 NCC 以前的业务逻辑,支持外部通过 record 中的 isleaf 字段,判断是否为叶子节点 // record['_isLeaf'] = typeof record['isleaf'] === 'boolean' ? record['isleaf'] : record['_isLeaf']; if(typeof record['isleaf'] === 'boolean' ){ record['_isLeaf'] = record['isleaf']; //如果isleaf存在并且为boolean的情况下才生成_isLeaf,否则无需生成 } // _isLeaf 字段是在 bigData 里添加的,只有层级树大数据场景需要该字段 // _isLeaf 有三种取值情况:true / false / null。(Table内部字段) const _isLeaf = typeof record['_isLeaf'] === 'boolean' ? record['_isLeaf'] : null; const childrenColumn = _isLeaf ? false : record[childrenColumnName]; const isRowExpanded = this.isRowExpanded(record, i); let expandedRowContent; let expandedContentHeight = 0; //fixedIndex一般是跟index是一个值的,只有是树结构时,会讲子节点的值也累计上 let fixedIndex = i; //判断是否是tree结构 if (this.treeType) { fixedIndex = this.treeRowIndex; } if (expandedRowRender && isRowExpanded) { expandedRowContent = expandedRowRender(record, fixedIndex+lazyCurrentIndex, indent); expandedContentHeight = parseInt(expandedRowContent.props && expandedRowContent.props.style && expandedRowContent.props.style.height?expandedRowContent.props.style.height:0); } //只有当使用expandedRowRender参数的时候才去识别isHiddenExpandIcon(隐藏行展开的icon) if (expandedRowRender && typeof props.haveExpandIcon == 'function') { isHiddenExpandIcon = props.haveExpandIcon(record, i); } if(props.bodyDisplayInRow){//内容显示不换行,即显示为"..." if(anyColumnsFixed){//存在固定列则强制同步行高度,以确保行不会错位 height = props.height ? props.height : fixedColumnsBodyRowsHeight[fixedIndex]; }else{ //不存在固定列,则按指定高度呈现行 height = props.height || 40; } }else{//内容自适应行高 if(anyColumnsFixed){//存在固定列则强制同步行高度,以确保行不会错位 height = fixedColumnsBodyRowsHeight[fixedIndex]; }else{ //不存在固定列,则按内容高度自行呈现 } } // if (props.bodyDisplayInRow && props.height) { // height = props.height // } else if(fixed || props.heightConsistent) { // height = fixedColumnsBodyRowsHeight[fixedIndex]; // } let className = rowClassName(record, fixedIndex+lazyCurrentIndex, indent); //合计代码如果是最后一行并且有合计功能时,最后一行为合计列 if(i == data.length -1 && props.showSum){ className = className + ' sumrow'; } let paramRootIndex = rootIndex; //小于0说明为第一层节点,她的子孙节点要保存自己的根节点 if(paramRootIndex<0){ paramRootIndex = i+lazyParentIndex; } let index = i; if(rootIndex ==-1){ index = i+lazyParentIndex } if(lazyLoadEnable && this.treeType && (record.index <lazyCurrentIndex || record.index > lazyEndIndex)){ // 大数据表格下,如果是树表,父节点如果已经不在区域范围则无需渲染dom,解决快速向上滚动父级树节点闪现的问题 fixedIndex--; this.treeRowIndex--; }else{ rst.push( <TableRow onPaste={onPaste} indent={indent} indentSize={props.indentSize} needIndentSpaced={needIndentSpaced} className={`${className}`} record={record} hasLeftFixed={hasLeftFixed} expandIconAsCell={props.expandIconAsCell} onDestroy={this.onRowDestroy} index={index} visible={visible} expandRowByClick={expandRowByClick} onExpand={this.onExpanded} expandable={expandedRowRender || ((childrenColumn && childrenColumn.length > 0) ? true : _isLeaf === false)} expanded={isRowExpanded} clsPrefix={`${props.clsPrefix}-row`} childrenColumnName={childrenColumnName} columns={leafColumns} expandIconColumnIndex={expandIconColumnIndex} onRowClick={onRowClick} onRowDoubleClick={onRowDoubleClick} height={height} isHiddenExpandIcon={isHiddenExpandIcon} onHover={this.handleRowHover} key={"table_row_"+key} hoverKey={key} ref={rowRef} store={this.store} fixed={fixed} expandedContentHeight={expandedContentHeight} setRowHeight={props.setRowHeight} setRowParentIndex={props.setRowParentIndex} treeType={childrenColumn||this.treeType?true:false} fixedIndex={fixedIndex+lazyCurrentIndex} rootIndex = {rootIndex} syncHover = {props.syncHover} bodyDisplayInRow = {props.bodyDisplayInRow} rowDraggAble={props.rowDraggAble} useDragHandle={props.useDragHandle} contentTable={this.contentTable} tableUid = {this.tableUid} expandedIcon={props.expandedIcon} collapsedIcon={props.collapsedIcon} lazyStartIndex = {lazyCurrentIndex} lazyEndIndex = {lazyEndIndex} centerColumnsLength={this.centerColumnsLength} leftColumnsLength={this.leftColumnsLength} expandIconCellWidth={expandIconCellWidth} getCellClassName = {props.getCellClassName} /> ); } this.treeRowIndex++; const subVisible = visible && isRowExpanded; if (expandedRowContent && isRowExpanded) { rst.push(this.getExpandedRow( key, expandedRowContent, subVisible, expandedRowClassName(record, i, indent), fixed, record, index )); } if (childrenColumn) { this.isTreeType = true; //增加该标志位,为了兼容老版本,不修改以前的 `this.treeType` 的相关逻辑 this.treeType = true;//证明是tree表形式visible = {true} rst = rst.concat(this.getRowsByData( childrenColumn, subVisible, indent + 1, columns, fixed,paramRootIndex )); } } if(props.lazyLoad && props.lazyLoad.sufHeight && indent == 0){ //console.log("AAA--->lazyLoad---last-->"+props.lazyLoad.su