UNPKG

antd-table-infinity

Version:

An infinite scroll component based on antd table that supports virtual scrolling & high-performance form http://keruyun.com/

704 lines (593 loc) 27.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InfinityTable = exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _reactDom = _interopRequireDefault(require("react-dom")); var _propTypes = require("prop-types"); var _antd = require("antd"); var _lodash = _interopRequireDefault(require("lodash.throttle")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const noop = () => {}; const fetchDebounce = (() => { const loading = []; return (_ref) => { let page = _ref.page, pageSize = _ref.pageSize, onFetch = _ref.onFetch; const now = Date.now(); if (!loading[page] || loading[page] && now - loading[page] > 1000) { onFetch({ page, pageSize }); } loading[page] = now; }; })(); function getCachePage(_ref2) { let step = _ref2.step, maxPage = _ref2.maxPage, pageSize = _ref2.pageSize, onFetch = _ref2.onFetch, loading = _ref2.loading, cacheData = _ref2.cacheData, currentPage = _ref2.currentPage; const pageBefore = currentPage - step; const pageAfter = currentPage + step; const cachePageDataBefore = cacheData[pageBefore]; const cachePageData = cacheData[currentPage]; const cachePageDataAfter = cacheData[pageAfter]; if (!loading) { !cachePageData && currentPage > 0 && currentPage <= maxPage && fetchDebounce({ page: currentPage, pageSize, onFetch }); !cachePageDataBefore && pageBefore > 0 && pageBefore <= maxPage && fetchDebounce({ page: pageBefore, pageSize, onFetch }); !cachePageDataAfter && pageAfter > 0 && pageAfter <= maxPage && fetchDebounce({ page: pageAfter, pageSize, onFetch }); } let lastOwnDataPage = currentPage; if (cachePageDataAfter) { lastOwnDataPage = pageAfter; } else if (cachePageData) { lastOwnDataPage = currentPage; } else if (cachePageDataBefore) { lastOwnDataPage = pageBefore; } return [cachePageDataBefore || [], cachePageData || [], cachePageDataAfter || [], lastOwnDataPage]; } const computeState = (_ref3, _ref4) => { let pageSize = _ref3.pageSize, onFetch = _ref3.onFetch, loading = _ref3.loading, total = _ref3.total, cachePages = _ref3.bidirectionalCachePages, _ref3$dataSource = _slicedToArray(_ref3.dataSource, 2), page = _ref3$dataSource[0], data = _ref3$dataSource[1]; let maxPage = _ref4.maxPage, currentPage = _ref4.currentPage, cacheData = _ref4.cacheData, rowHeight = _ref4.rowHeight; let bidirectionalCachePages = cachePages; let newCacheData = cacheData; if (cachePages < 1) { bidirectionalCachePages = 1; } if (bidirectionalCachePages * 2 + 1 < maxPage) { let startPage = currentPage - bidirectionalCachePages; startPage = startPage < 1 ? 1 : startPage; let endPage = currentPage + bidirectionalCachePages; endPage = endPage > maxPage ? maxPage : endPage; cacheData[page] = data; // eslint-disable-line newCacheData = Array.from({ length: maxPage }); Array.prototype.splice.apply(newCacheData, [startPage, endPage - startPage + 1].concat(cacheData.slice(startPage, endPage + 1))); } newCacheData[page] = data; const _getCachePage = getCachePage({ step: 1, maxPage, pageSize, onFetch, loading, cacheData: newCacheData, currentPage }), _getCachePage2 = _slicedToArray(_getCachePage, 4), cachePageDataBefore = _getCachePage2[0], cachePageData = _getCachePage2[1], cachePageDataAfter = _getCachePage2[2], lastOwnDataPage = _getCachePage2[3]; const upperHeight = Math.round((currentPage - 1 - (cachePageDataBefore.length ? 1 : 0)) * pageSize * rowHeight); const underHeight = Math.round( // 已经是最后一页,直接返回0,否则如果有零头total % pageSize,需要加上不满一个page的零头lastOwnDataPageLength,但需要少加一个整页pageSize maxPage === lastOwnDataPage ? 0 : ((maxPage - lastOwnDataPage) * pageSize + total % pageSize) * rowHeight); const dataSource = cachePageDataBefore.concat(cachePageData).concat(cachePageDataAfter); return { hasCacheBefore: !!cachePageDataBefore.length, hasCache: !!cachePageData.length, hasCacheAfter: !!cachePageDataAfter.length, cacheData: newCacheData, dataSource, underHeight, upperHeight }; }; /* eslint-disable react/no-redundant-should-component-update */ class InfinityTable extends _react.Component { constructor() { var _this; _this = super(...arguments); _defineProperty(this, "state", { scrollTop: 0, // 滚动条位置 dataSource: [], // DOM上显示的数据 rowHeight: 0, // 每行的实际高度 cacheData: [], // 缓存的数据集大小 currentPage: 1, // 当前页位置 underHeight: 0, // 下撑高 upperHeight: 0 // 上撑高 }); _defineProperty(this, "isInitial", true); _defineProperty(this, "isReady", false); _defineProperty(this, "isPageBoundary", false); _defineProperty(this, "isPaginationClick", false); _defineProperty(this, "refUpperPlaceholder", null); _defineProperty(this, "refUnderPlaceholder", null); _defineProperty(this, "refLoadingPlaceholder", null); _defineProperty(this, "refScroll", null); _defineProperty(this, "refTable", null); _defineProperty(this, "refFooter", null); _defineProperty(this, "refPageBoundaryBefore", null); _defineProperty(this, "refPageBoundaryAfter", null); _defineProperty(this, "ioTargetState", { refUnderPlaceholder: null, refUpperPlaceholder: null, refTable: null, refPageBoundaryBefore: null, refPageBoundaryAfter: null }); _defineProperty(this, "scrollToPage", function () { const pageSize = _this.props.pageSize; const rowHeight = _this.state.rowHeight; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } const page = args[0]; _this.refScroll.scrollTop = (page - 1) * pageSize * rowHeight + 1; // Bug fix: + 1个像素,点击页码向后翻页时存在少一个像素就变成上一页的bug _this.isPaginationClick = true; _this.props.pagination && _this.props.pagination.onChange && _this.props.pagination.onChange(...args); }); _defineProperty(this, "updateTable", () => { const tableHeight = this.refTable.clientHeight; const scrollTop = this.refScroll.scrollTop; let _this$state = this.state, rowHeight = _this$state.rowHeight, maxPage = _this$state.maxPage; const _this$props = this.props, pageSize = _this$props.pageSize, total = _this$props.total, debug = _this$props.debug; if (this.isInitial) { // 还在初始状态 maxPage = Math.ceil(total / pageSize); const length = this.state.dataSource.length; rowHeight = tableHeight / length; if (rowHeight) { // 当行高出现,表示初次呈现数据数时 this.isInitial = false; this.initialReslove(); } } let currentPage = Math.floor(scrollTop / (pageSize * rowHeight)) + 1 || 1; currentPage = currentPage > maxPage ? maxPage : currentPage; debug && console.log('updateTable', { currentPage }); this.setState({ direction: this.refScroll.scrollTop - this.state.scrollTop < 0 ? 'up' : 'down', scrollTop: this.refScroll.scrollTop, maxPage, currentPage, rowHeight } // () => console.log('computeState done', this.state), ); }); } static PlaceHolder(_ref5) { let height = _ref5.height, domNode = _ref5.domNode, loading = _ref5.loading, loadingIndicator = _ref5.loadingIndicator; return domNode && _reactDom.default.createPortal(_react.default.createElement("div", { style: { height: `${height}px` } }, loading && loadingIndicator, " "), domNode); } static LoadingPlaceHolder(_ref6) { let domNode = _ref6.domNode, loading = _ref6.loading, loadingIndicator = _ref6.loadingIndicator; return domNode && _reactDom.default.createPortal(loading ? loadingIndicator : _react.default.createElement("div", null), domNode); } static getDerivedStateFromProps(props, prevState) { return computeState(props, prevState); } componentDidMount() { /* eslint-disable */ this.refRoot = _reactDom.default.findDOMNode(this); this.refScroll = this.refRoot.getElementsByClassName('ant-table-body')[0]; this.refTable = this.refScroll.getElementsByTagName('tbody')[0]; /* eslint-enabled */ this.createUnderPlaceholder(); this.createUpperPlaceholder(); this.setStateWithThrottle = (0, _lodash.default)(this.updateTable, 0); this.props.onScroll && this.refScroll.addEventListener('scroll', this.props.onScroll); if (this.refScroll) { this.io = new IntersectionObserver(changes => { const debug = this.props.debug; let shouldUpdate = true; this.ioTargetState = changes.reduce((result, change) => { const ret = _objectSpread({}, result); switch (change.target) { case this.refPageBoundaryBefore: ret.refPageBoundaryBefore = change; // Bug fix: // 向下滚动的时候,如果边界第一行数据触发,不需要更新视图,因为上一页的最后一行已经触发了视图更新, // 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码 if (!this.isPaginationClick && changes.length === 1 && this.state.direction === 'down') { shouldUpdate = false; } break; case this.refPageBoundaryAfter: ret.refPageBoundaryAfter = change; // Bug fix: // 向上滚动的时候,如果边界最后行数据触发,不需要更新视图,因为上一页的第一行已经触发了视图更新 // 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码 if (!this.isPaginationClick && changes.length === 1 && this.state.direction === 'up') { shouldUpdate = false; } break; default: // console.log(change) } return ret; }, this.ioTargetState); this.isPaginationClick = false; debug && console.log('shouldUpdate:IntersectionObserver', { shouldUpdate, changes }); shouldUpdate && this.setStateWithThrottle(); }, { root: this.refScroll, threshold: [0, 1] }); this.toggleObserver(); } this.props.onFetch({ page: 1, pageSize: this.props.pageSize }); new Promise(reslove => { this.initialReslove = reslove; }).then(() => { const _this$props2 = this.props, pageSize = _this$props2.pageSize, _this$props2$paginati = _this$props2.pagination.defaultCurrent, defaultCurrent = _this$props2$paginati === void 0 ? 1 : _this$props2$paginati; this.createLoadingPlaceholder(); // fullLoading this.scrollToPage(defaultCurrent); const visibleRowCount = Math.round(this.refScroll.clientHeight / this.state.rowHeight); this.isReady = true; if (pageSize < visibleRowCount) { console.warn(`pagesize(${pageSize}) less than visible row count(${visibleRowCount}), maybe you set error!`); } }); } shouldComponentUpdate(nextProps, nextState) { const pageSize = nextProps.pageSize, debug = nextProps.debug; const maxPage = nextState.maxPage, currentPage = nextState.currentPage, dataSource = nextState.dataSource, direction = nextState.direction, rowHeight = nextState.rowHeight; let shouldUpdate = true; // 有且仅有当前页上下边界同时触发时,表示更换边界,不需要更新 if (this.isPageBoundary) { shouldUpdate = false; this.isPageBoundary = false; } debug && console.log('shouldUpdate:updateBoundary', { shouldUpdate }); if (shouldUpdate && !this.isInitial) { let currentPageReal = currentPage; // 由于state中的currentPage延迟与真实的currentPage不一致,当出现这种情况时,强制updateTable() currentPageReal = Math.floor(this.refScroll.scrollTop / (pageSize * rowHeight)) + 1 || 1; currentPageReal = currentPageReal > maxPage ? maxPage : currentPageReal; if (currentPageReal !== currentPage) { this.updateTable(); shouldUpdate = false; } debug && console.log('shouldUpdate:currentPageReal', { currentPageReal, currentPage, shouldUpdate }); } if (shouldUpdate) { const _this$ioTargetState = this.ioTargetState, refPageBoundaryBefore = _this$ioTargetState.refPageBoundaryBefore, refPageBoundaryAfter = _this$ioTargetState.refPageBoundaryAfter; switch (direction) { case 'up': if (this.state.hasCacheAfter && currentPage < maxPage - 2 && // Bug fix: 如果是最后三页向后点击切换,需要刷新视图,否则页码表记停留在前一页 refPageBoundaryBefore && refPageBoundaryBefore.intersectionRatio > 0) shouldUpdate = false; break; case 'down': if (this.state.currentPage === currentPage && this.state.hasCacheAfter && // Bug fix: 可能存在3页数据已经加载到了, 但之前没有刷新的情况,所以需要刷新,判断特征是之前的数据小于3页 refPageBoundaryAfter && refPageBoundaryAfter.intersectionRatio > 0) shouldUpdate = false; } debug && console.log('shouldUpdate:verboseBoundary', { shouldUpdate, direction, dataSource, Before: refPageBoundaryBefore && refPageBoundaryBefore.intersectionRatio, After: refPageBoundaryAfter && refPageBoundaryAfter.intersectionRatio }); } // if (shouldUpdate) { // shouldUpdate = [1, maxPage, maxPage - 1, maxPage - 2].includes(currentPage) // ? dataSource.length > 0 // : [ // // 如果已经加载3页数据,需要更新视图,否则不在 fullLoading 状态,即使数据不满3页也需要更新视图 // // 兼容部份项目,每页,可能多一个条目的情况,如一系列数据,有个合计行 // ...(this.fullLoading ? [] : [0, pageSize, pageSize + 1, pageSize * 2, pageSize * 2 + 1, pageSize * 2 + 2]), // pageSize * 3, // pageSize * 3 + 1, // pageSize * 3 + 2, // pageSize * 3 + 3, // ].includes(dataSource.length) // debug && // console.log('shouldUpdate:3Page', { // currentPage, // dataSource, // shouldUpdate, // state: this.state, // nextState, // }) // } return shouldUpdate; } componentDidUpdate(preProps, preState) { const _this$state2 = this.state, hasCache = _this$state2.hasCache, hasCacheBefore = _this$state2.hasCacheBefore, currentPage = _this$state2.currentPage, dataSource = _this$state2.dataSource, maxPage = _this$state2.maxPage; const _this$props3 = this.props, pageSize = _this$props3.pageSize, debug = _this$props3.debug; if (!this.isInitial) { let before, after; if (hasCache && hasCacheBefore) { if (currentPage === 1 || currentPage === maxPage - 1) { before = 0; after = pageSize - 1; } else if (currentPage === maxPage) { before = 0; after = dataSource.length - 1; } else { before = pageSize; after = pageSize * 2 - 1; } if (this.refPageBoundaryBefore !== this.refTable.children[before]) { this.refPageBoundaryBefore && this.io.unobserve(this.refPageBoundaryBefore); this.refPageBoundaryAfter && this.io.unobserve(this.refPageBoundaryAfter); this.refPageBoundaryBefore = this.refTable.children[before]; this.refPageBoundaryAfter = this.refTable.children[after]; this.refPageBoundaryAfter && this.io.observe(this.refPageBoundaryAfter); this.refPageBoundaryBefore && this.io.observe(this.refPageBoundaryBefore); debug && this.refPageBoundaryBefore && console.log('componentDidUpdate', this.refPageBoundaryBefore.innerText); debug && this.refPageBoundaryAfter && console.log('componentDidUpdate', this.refPageBoundaryAfter.innerText); this.isPageBoundary = true; } } const emptyPlaceholder = this.refRoot.querySelector('.ant-table-placeholder'); emptyPlaceholder && (emptyPlaceholder.style.display = 'none'); } } componentWillUnmount() { this.props.onScroll && this.refScroll.removeEventListener('scroll', this.props.onScroll); this.io.disconnect(); } createLoadingPlaceholder() { const refLoadingPlaceholder = document.createElement('div'); refLoadingPlaceholder.setAttribute('id', 'refLoadingPlaceholder'); const clientRect = this.refScroll.getBoundingClientRect(); refLoadingPlaceholder.setAttribute('style', `position:fixed; width:${clientRect.width}px; height:${clientRect.height}px`); this.refScroll.insertBefore(refLoadingPlaceholder, this.refScroll.firstChild); this.refLoadingPlaceholder = refLoadingPlaceholder; } // 创建底部填充块 createUnderPlaceholder() { const refUnderPlaceholder = document.createElement('div'); refUnderPlaceholder.setAttribute('id', 'refUnderPlaceholder'); this.refScroll.appendChild(refUnderPlaceholder); this.refUnderPlaceholder = refUnderPlaceholder; } // 创建顶部填充块 createUpperPlaceholder() { const refUpperPlaceholder = document.createElement('div'); refUpperPlaceholder.setAttribute('id', 'refUpperPlaceholder'); this.refScroll.insertBefore(refUpperPlaceholder, this.refScroll.firstChild); this.refUpperPlaceholder = refUpperPlaceholder; } toggleObserver() { let condition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; if (condition) { this.io.observe(this.refUpperPlaceholder); this.io.observe(this.refUnderPlaceholder); this.io.observe(this.refTable); this.refPageBoundaryBefore && this.io.observe(this.refPageBoundaryBefore); this.refPageBoundaryAfter && this.io.observe(this.refPageBoundaryAfter); } else { this.io.unobserve(this.refUpperPlaceholder); this.io.unobserve(this.refUnderPlaceholder); this.io.unobserve(this.refTable); this.refPageBoundaryBefore && this.io.unobserve(this.refPageBoundaryBefore); this.refPageBoundaryAfter && this.io.unobserve(this.refPageBoundaryAfter); } } render() { const _this$props4 = this.props, pageSize = _this$props4.pageSize, loadingIndicator = _this$props4.loadingIndicator, loading = _this$props4.loading, total = _this$props4.total, columns = _this$props4.columns, debug = _this$props4.debug, forwardedRef = _this$props4.forwardedRef, pagination = _this$props4.pagination, rest = _objectWithoutProperties(_this$props4, ["pageSize", "loadingIndicator", "loading", "total", "columns", "debug", "forwardedRef", "pagination"]); const _this$state3 = this.state, dataSource = _this$state3.dataSource, upperHeight = _this$state3.upperHeight, underHeight = _this$state3.underHeight, cacheData = _this$state3.cacheData, currentPage = _this$state3.currentPage; this.fullLoading = !cacheData[currentPage]; const fullLoading = this.fullLoading; debug && console.log('%c Rendering', 'color:#f00;font-weight:bold'); return _react.default.createElement(_react.Fragment, null, _react.default.createElement(InfinityTable.LoadingPlaceHolder, { domNode: this.refLoadingPlaceholder, loading: fullLoading, loadingIndicator: _react.default.createElement(_antd.Spin, { tip: "Loading..." }) }), _react.default.createElement(InfinityTable.PlaceHolder, { height: upperHeight, domNode: this.refUpperPlaceholder, loading: loading && !fullLoading, loadingIndicator: loadingIndicator }), _react.default.createElement(InfinityTable.PlaceHolder, { height: underHeight, domNode: this.refUnderPlaceholder, loading: loading && !fullLoading, loadingIndicator: loadingIndicator }), total && pagination && ['top', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({ showQuickJumper: true }, pagination, { onChange: this.scrollToPage, current: currentPage, pageSize: pageSize, showSizeChanger: false, total: total, className: `infinity-page-table-pagination ${pagination && pagination.className ? pagination.className : ''}` })), _react.default.createElement(_antd.Table, _extends({ rowKey: record => record.key }, rest, { ref: forwardedRef, columns: columns, dataSource: dataSource, pagination: false, className: `infinity-page-table ${rest.className ? rest.className : ''}` })), total && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({ showQuickJumper: true }, pagination, { onChange: this.scrollToPage, current: currentPage, pageSize: pageSize, showSizeChanger: false, total: total, className: `infinity-page-table-pagination ${pagination && pagination.className ? pagination.className : ''}` }))); } } exports.InfinityTable = InfinityTable; InfinityTable.defaultProps = { // loading 效果, A visual react component for Loading status loadingIndicator: _react.default.createElement("div", { style: { textAlign: 'center', paddingTop: 20, paddingBottom: 20, border: '1px solid #e8e8e8' } }, _react.default.createElement(_antd.Spin, { tip: "Loading..." })), pagination: { defaultCurrent: 1 }, // 分页器 onScroll: null, // 滚动事件 onFetch: noop, // 滚动到低部触发Fetch方法 bidirectionalCachePages: Infinity, // 当前页前后的缓存页码数量,默认为无限 total: 0, // 总共数据条数 debug: false, // display console log for debug loading: false, // 是否loading状态 pageSize: 30 // 每次Loading数据量,pageSize * 3 = 最大真实DOM大小,Reality DOM row count }; InfinityTable.propTypes = { // loading 效果 className: _propTypes.string, loadingIndicator: _propTypes.element, onScroll: _propTypes.func, // 滚动事件 pagination: (0, _propTypes.oneOfType)([_propTypes.bool, (0, _propTypes.shape)({ className: _propTypes.string, position: (0, _propTypes.oneOf)(['both', 'top', 'bottom']), className: _propTypes.string, defaultCurrent: _propTypes.number, hideOnSinglePage: _propTypes.bool, itemRender: _propTypes.func, showQuickJumper: _propTypes.bool, showTotal: _propTypes.func, simple: _propTypes.bool, size: _propTypes.string, onChange: _propTypes.func })]), onFetch: _propTypes.func.isRequired, // 滚动触发Fetch方法 pageSize: _propTypes.number.isRequired, bidirectionalCachePages: _propTypes.number.isRequired, total: _propTypes.number.isRequired, dataSource: _propTypes.array.isRequired, columns: _propTypes.array.isRequired, forwardedRef: _propTypes.object, debug: _propTypes.bool, loading: _propTypes.bool.isRequired }; var _default = _react.default.forwardRef((props, ref) => _react.default.createElement(InfinityTable, _extends({}, props, { forwardedRef: ref }))); exports.default = _default;