UNPKG

vxe-table

Version:

A PC-end table component based on Vxe UI, supporting copy-paste, data pivot table, and high-performance virtual list table solution.

14,792 lines 721 kB
import { h, reactive, ref, provide, inject, nextTick, Teleport, onActivated, onDeactivated, onBeforeUnmount, onUnmounted, watch, computed, onMounted } from 'vue';
import { defineVxeComponent } from '../../ui/src/comp';
import XEUtils from 'xe-utils';
import { initTpImg, getTpImg, isPx, isScale, hasClass, addClass, removeClass, wheelScrollTopTo, wheelScrollLeftTo, getEventTargetNode, getPaddingTopBottomSize, setScrollTop, setScrollLeft, toCssUnit, hasControlKey, checkTargetElement, hasEventInputTarget } from '../../ui/src/dom';
import { getLastZIndex, nextZIndex, hasChildrenList, getFuncText, isEnableConf, formatText, eqEmptyValue } from '../../ui/src/utils';
import { VxeUI } from '../../ui';
import { createReactData, createInternalData, getRowUniqueId, createRowId, clearTableAllStatus, getColumnList, toFilters, hasDeepKey, getRowkey, getRowid, rowToVisible, colToVisible, getCellValue, setCellValue, handleRowidOrRow, handleFieldOrColumn, toTreePathSeq, restoreScrollLocation, getRootColumn, getRefElem, getColReMinWidth, getColReMaxWidth, createHandleUpdateRowId, createHandleGetRowId, getCalcHeight, getCellRestHeight, getLastChildColumn, getRowMaxHeight, handleCustomStoreConfig, encodeRowid } from './util';
import { getSlotVNs } from '../../ui/src/vn';
import { moveRowAnimateToTb, clearRowAnimate, moveColAnimateToLr, clearColAnimate } from '../../ui/src/anime';
import { createComponentLog } from '../../ui/src/log';
import { getCrossTableDragRowInfo } from './store';
import Cell from './cell';
import TableBodyComponent from './body';
import TableHeaderComponent from './header';
import TableFooterComponent from './footer';
import { tableProps } from './props';
import { tableEmits } from './emits';
import TableCustomPanelComponent from '../module/custom/panel';
import TableFilterPanelComponent from '../module/filter/panel';
import TableImportPanelComponent from '../module/export/import-panel';
import TableExportPanelComponent from '../module/export/export-panel';
import TableMenuPanelComponent from '../module/menu/panel';
import '../module/filter/hook';
import '../module/menu/hook';
import '../module/edit/hook';
import '../module/export/hook';
import '../module/keyboard/hook';
import '../module/validator/hook';
import '../module/custom/hook';
import '../render';
const { warnLog, errLog } = createComponentLog('table');
const { getConfig, getIcon, getI18n, renderer, formats, createEvent, globalResize, interceptor, hooks, globalEvents, GLOBAL_EVENT_KEYS, useFns, renderEmptyElement } = VxeUI;
const supportMaxRow = 5e6;
const customStorageKey = 'VXE_CUSTOM_STORE';
const maxYHeight = 5e6;
const maxXWidth = 5e6;
const sourceType = 'table';
let crossTableDragRowObj = null;
export default defineVxeComponent({
    name: 'VxeTable',
    props: tableProps,
    emits: tableEmits,
    setup(props, context) {
        const { slots, emit } = context;
        const xID = XEUtils.uniqueId();
        const browseObj = XEUtils.browse();
        // 使用已安装的组件,如果未安装则不渲染
        const VxeUILoadingComponent = VxeUI.getComponent('VxeLoading');
        const VxeUITooltipComponent = VxeUI.getComponent('VxeTooltip');
        const $xeModal = inject('$xeModal', null);
        const $xeTabs = inject('$xeTabs', null);
        const $xeParentTable = inject('$xeTable', null);
        const $xeSplitter = inject('$xeSplitter', null);
        const $xeGrid = inject('$xeGrid', null);
        const $xeGantt = inject('$xeGantt', null);
        const $xeGGWrapper = $xeGrid || $xeGantt;
        const { computeSize } = useFns.useSize(props);
        const crossTableDragRowInfo = getCrossTableDragRowInfo();
        const reactData = reactive(createReactData());
        const internalData = createInternalData();
        let tableMethods = {};
        let tablePrivateMethods = {};
        const refElem = ref();
        const refVarElem = ref();
        const refTooltip = ref();
        const refCommTooltip = ref();
        const refValidTooltip = ref();
        const refTableMenu = ref();
        const refTableFilter = ref();
        const refTableCustom = ref();
        const refTableViewportElem = ref();
        const refTableHeader = ref();
        const refTableBody = ref();
        const refTableFooter = ref();
        const refTableLeftHeader = ref();
        const refTableLeftBody = ref();
        const refTableLeftFooter = ref();
        const refTableRightHeader = ref();
        const refTableRightBody = ref();
        const refTableRightFooter = ref();
        const refTeleportWrapper = ref();
        const refPopupWrapperElem = ref();
        const refCustomContainerElem = ref();
        const refLeftContainer = ref();
        const refRightContainer = ref();
        const refColResizeBar = ref();
        const refRowResizeBar = ref();
        const refEmptyPlaceholder = ref();
        const refDragTipElem = ref();
        const refDragRowLineElem = ref();
        const refDragColLineElem = ref();
        const refRowExpandElem = ref();
        const refRowExpandYSpaceElem = ref();
        const refScrollXVirtualElem = ref();
        const refScrollYVirtualElem = ref();
        const refScrollXHandleElem = ref();
        const refScrollXLeftCornerElem = ref();
        const refScrollXRightCornerElem = ref();
        const refScrollYHandleElem = ref();
        const refScrollYTopCornerElem = ref();
        const refScrollXWrapperElem = ref();
        const refScrollYWrapperElem = ref();
        const refScrollYBottomCornerElem = ref();
        const refScrollXSpaceElem = ref();
        const refScrollYSpaceElem = ref();
        let $xeToolbar;
        const computeTableId = computed(() => {
            const { id } = props;
            if (id) {
                if (XEUtils.isFunction(id)) {
                    return `${id({ $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt }) || ''}`;
                }
                return `${id}`;
            }
            return '';
        });
        const computeRowField = computed(() => {
            const rowOpts = computeRowOpts.value;
            return `${props.rowId || rowOpts.keyField || '_X_ROW_KEY'}`;
        });
        const computeValidOpts = computed(() => {
            const opts = Object.assign({}, getConfig().table.validConfig, props.validConfig);
            // 兼容老版本
            if (XEUtils.isBoolean(opts.showMessage)) {
                opts.showErrorMessage = opts.showMessage;
            }
            return opts;
        });
        /**
         * @deprecated
         */
        const computeSXOpts = computed(() => {
            const virtualXOpts = computeVirtualXOpts.value;
            return virtualXOpts;
        });
        const computeScrollXThreshold = computed(() => {
            const virtualXOpts = computeVirtualXOpts.value;
            const { threshold } = virtualXOpts;
            if (threshold) {
                return XEUtils.toNumber(threshold);
            }
            return 0;
        });
        /**
         * @deprecated
         */
        const computeSYOpts = computed(() => {
            const virtualYOpts = computeVirtualYOpts.value;
            return virtualYOpts;
        });
        const computeVirtualXOpts = computed(() => {
            const { virtualXConfig, scrollX } = props;
            const globalVirtualXConfig = getConfig().table.virtualXConfig;
            const globalScrollX = getConfig().table.scrollX;
            if (virtualXConfig) {
                return Object.assign({}, globalVirtualXConfig, virtualXConfig);
            }
            if (scrollX) {
                // 已废弃,保留兼容
                return Object.assign({}, globalScrollX, scrollX);
            }
            if (globalVirtualXConfig) {
                return Object.assign({}, globalVirtualXConfig, virtualXConfig);
            }
            // 已废弃,保留兼容
            return Object.assign({}, globalScrollX, scrollX);
        });
        const computeVirtualYOpts = computed(() => {
            const { virtualYConfig, scrollY } = props;
            const globalVirtualYConfig = getConfig().table.virtualYConfig;
            const globalScrollY = getConfig().table.scrollY;
            if (virtualYConfig) {
                return Object.assign({}, globalVirtualYConfig, virtualYConfig);
            }
            if (scrollY) {
                // 已废弃,保留兼容
                return Object.assign({}, globalScrollY, scrollY);
            }
            if (globalVirtualYConfig) {
                return Object.assign({}, globalVirtualYConfig, virtualYConfig);
            }
            // 已废弃,保留兼容
            return Object.assign({}, globalScrollY, scrollY);
        });
        const computeScrollbarOpts = computed(() => {
            return Object.assign({}, getConfig().table.scrollbarConfig, props.scrollbarConfig);
        });
        const computeScrollbarXOpts = computed(() => {
            var _a;
            const scrollbarOpts = computeScrollbarOpts.value;
            return Object.assign({}, scrollbarOpts.x, ((_a = props.scrollbarConfig) === null || _a === void 0 ? void 0 : _a.x) || {});
        });
        const computeScrollbarYOpts = computed(() => {
            var _a;
            const scrollbarOpts = computeScrollbarOpts.value;
            return Object.assign({}, scrollbarOpts.y, ((_a = props.scrollbarConfig) === null || _a === void 0 ? void 0 : _a.y) || {});
        });
        const computeScrollbarXToTop = computed(() => {
            const scrollbarXOpts = computeScrollbarXOpts.value;
            return scrollbarXOpts.position === 'top';
        });
        const computeScrollbarYToLeft = computed(() => {
            const scrollbarYOpts = computeScrollbarYOpts.value;
            return scrollbarYOpts.position === 'left';
        });
        const computeScrollYThreshold = computed(() => {
            const virtualYOpts = computeVirtualYOpts.value;
            const { threshold } = virtualYOpts;
            if (threshold) {
                return XEUtils.toNumber(threshold);
            }
            return 0;
        });
        const computeRowHeightMaps = computed(() => {
            return reactData.rowHeightStore;
        });
        const computeDefaultRowHeight = computed(() => {
            const vSize = computeSize.value;
            const rowHeightMaps = computeRowHeightMaps.value;
            return rowHeightMaps[vSize || 'default'] || 18;
        });
        const computeColumnOpts = computed(() => {
            return Object.assign({}, getConfig().table.columnConfig, props.columnConfig);
        });
        const computeCurrentColumnOpts = computed(() => {
            return Object.assign({}, getConfig().table.currentColumnConfig, props.currentColumnConfig);
        });
        const computeCellOpts = computed(() => {
            const cellOpts = Object.assign({}, getConfig().table.cellConfig, props.cellConfig);
            if (cellOpts.height) {
                cellOpts.height = XEUtils.toNumber(cellOpts.height);
            }
            return cellOpts;
        });
        const computeHeaderCellOpts = computed(() => {
            const headerCellOpts = Object.assign({}, getConfig().table.headerCellConfig, props.headerCellConfig);
            const defaultRowHeight = computeDefaultRowHeight.value;
            const cellOpts = computeCellOpts.value;
            let headCellHeight = XEUtils.toNumber(getCalcHeight(headerCellOpts.height || cellOpts.height));
            if ($xeGantt) {
                const { computeTaskViewScales } = $xeGantt.getComputeMaps();
                const taskViewScales = computeTaskViewScales.value;
                if (taskViewScales && taskViewScales.length > 2) {
                    const ganttMinHeadCellHeight = defaultRowHeight / 2 * taskViewScales.length;
                    headCellHeight = Math.max(ganttMinHeadCellHeight, headCellHeight);
                }
            }
            headerCellOpts.height = headCellHeight;
            return headerCellOpts;
        });
        const computeFooterCellOpts = computed(() => {
            const footerCellOpts = Object.assign({}, getConfig().table.footerCellConfig, props.footerCellConfig);
            const cellOpts = computeCellOpts.value;
            footerCellOpts.height = XEUtils.toNumber(getCalcHeight(footerCellOpts.height || cellOpts.height));
            return footerCellOpts;
        });
        const computeRowOpts = computed(() => {
            return Object.assign({}, getConfig().table.rowConfig, props.rowConfig);
        });
        const computeAggregateOpts = computed(() => {
            return Object.assign({}, getConfig().table.aggregateConfig || getConfig().table.rowGroupConfig, props.aggregateConfig || props.rowGroupConfig);
        });
        const computeRowGroupOpts = computed(() => {
            return computeAggregateOpts.value;
        });
        const computeAggregateMode = computed(() => {
            const aggregateOpts = computeAggregateOpts.value;
            return aggregateOpts.mode;
        });
        const computeAggregateAccuracyOpts = computed(() => {
            return Object.assign({}, getConfig().table.aggregateAccuracyConfig, props.aggregateAccuracyConfig);
        });
        const computeCurrentRowOpts = computed(() => {
            return Object.assign({}, getConfig().table.currentRowConfig, props.currentRowConfig);
        });
        const computeRowDragOpts = computed(() => {
            return Object.assign({}, getConfig().table.rowDragConfig, props.rowDragConfig);
        });
        const computeColumnDragOpts = computed(() => {
            return Object.assign({}, getConfig().table.columnDragConfig, props.columnDragConfig);
        });
        const computeResizeOpts = computed(() => {
            return Object.assign({}, getConfig().table.resizeConfig, props.resizeConfig);
        });
        const computeResizableOpts = computed(() => {
            return Object.assign({}, getConfig().table.resizableConfig, props.resizableConfig);
        });
        const computeSeqOpts = computed(() => {
            return Object.assign({ startIndex: 0 }, getConfig().table.seqConfig, props.seqConfig);
        });
        const computeRadioOpts = computed(() => {
            return Object.assign({}, getConfig().table.radioConfig, props.radioConfig);
        });
        const computeCheckboxOpts = computed(() => {
            return Object.assign({}, getConfig().table.checkboxConfig, props.checkboxConfig);
        });
        const computeTooltipOpts = computed(() => {
            return Object.assign({}, getConfig().tooltip, getConfig().table.tooltipConfig, props.tooltipConfig);
        });
        const computeHeaderTooltipOpts = computed(() => {
            return Object.assign({}, getConfig().tooltip, getConfig().table.headerTooltipConfig, props.headerTooltipConfig);
        });
        const computeFooterTooltipOpts = computed(() => {
            return Object.assign({}, getConfig().tooltip, getConfig().table.footerTooltipConfig, props.footerTooltipConfig);
        });
        const computeTableTipConfig = computed(() => {
            const { tooltipStore } = reactData;
            const tooltipOpts = computeTooltipOpts.value;
            return Object.assign({}, tooltipOpts, tooltipStore.currOpts);
        });
        const computeValidTipConfig = computed(() => {
            const tooltipOpts = computeTooltipOpts.value;
            return Object.assign({}, tooltipOpts);
        });
        const computeEditOpts = computed(() => {
            return Object.assign({}, getConfig().table.editConfig, props.editConfig);
        });
        const computeEditDirtyOpts = computed(() => {
            return Object.assign({}, getConfig().table.editDirtyConfig, props.editDirtyConfig);
        });
        const computeSortOpts = computed(() => {
            return Object.assign({ orders: ['asc', 'desc', null] }, getConfig().table.sortConfig, props.sortConfig);
        });
        const computeFilterOpts = computed(() => {
            return Object.assign({}, getConfig().table.filterConfig, props.filterConfig);
        });
        const computeFloatingFilterOpts = computed(() => {
            return Object.assign({}, getConfig().table.floatingFilterConfig, props.floatingFilterConfig);
        });
        const computeMouseOpts = computed(() => {
            return Object.assign({}, getConfig().table.mouseConfig, props.mouseConfig);
        });
        const computeAreaOpts = computed(() => {
            return Object.assign({}, getConfig().table.areaConfig, props.areaConfig);
        });
        const computeKeyboardOpts = computed(() => {
            return Object.assign({}, getConfig().table.keyboardConfig, props.keyboardConfig);
        });
        const computeClipOpts = computed(() => {
            return Object.assign({}, getConfig().table.clipConfig, props.clipConfig);
        });
        const computeUndoRedoHistoryOpts = computed(() => {
            return Object.assign({}, getConfig().table.undoRedoHistoryConfig, props.undoRedoHistoryConfig);
        });
        const computeFNROpts = computed(() => {
            const fnrOpts = computeFnrOpts.value;
            return fnrOpts;
        });
        const computeFnrOpts = computed(() => {
            return Object.assign({}, getConfig().table.fnrConfig, props.fnrConfig);
        });
        const computeMenuOpts = computed(() => {
            return Object.assign({}, getConfig().table.menuConfig, props.menuConfig);
        });
        const computeLeftFixedWidth = computed(() => {
            const { columnStore } = reactData;
            const { leftList } = columnStore;
            let leftWidth = 0;
            for (let i = 0; i < leftList.length; i++) {
                const column = leftList[i];
                leftWidth += column.renderWidth;
            }
            return leftWidth;
        });
        const computeRightFixedWidth = computed(() => {
            const { columnStore } = reactData;
            const { rightList } = columnStore;
            let leftWidth = 0;
            for (let i = 0; i < rightList.length; i++) {
                const column = rightList[i];
                leftWidth += column.renderWidth;
            }
            return leftWidth;
        });
        // 合并列是否超越冻结列
        const computeBodyMergeCoverFixed = computed(() => {
            const { columnStore, mergeBodyFlag } = reactData;
            const { mergeBodyList, visibleColumn } = internalData;
            const { leftList, rightList } = columnStore;
            const rscIndex = visibleColumn.length - rightList.length;
            if (mergeBodyFlag && (leftList.length || rightList.length)) {
                const lecIndex = leftList.length;
                for (let i = 0; i < mergeBodyList.length; i++) {
                    const { col, colspan } = mergeBodyList[i];
                    if (col < lecIndex && col + colspan > lecIndex) {
                        return true;
                    }
                    else if (col < rscIndex && col + colspan > rscIndex) {
                        return true;
                    }
                }
            }
            return false;
        });
        const computeIsHeaderRenderOptimize = computed(() => {
            const { spanMethod, footerSpanMethod, showHeaderOverflow: allColumnHeaderOverflow } = props;
            const { isGroup, scrollXLoad } = reactData;
            let isOptimizeMode = false;
            if (isGroup) {
                // 分组表头
            }
            else {
                // 如果是使用优化模式
                if (scrollXLoad && allColumnHeaderOverflow) {
                    if (spanMethod || footerSpanMethod) {
                        // 如果不支持优化模式
                    }
                    else {
                        isOptimizeMode = true;
                    }
                }
            }
            return isOptimizeMode;
        });
        const computeIsBodyRenderOptimize = computed(() => {
            const { spanMethod, footerSpanMethod } = props;
            const { scrollXLoad, scrollYLoad, isAllOverflow, expandColumn } = reactData;
            const bodyMergeCoverFixed = computeBodyMergeCoverFixed.value;
            const expandOpts = computeExpandOpts.value;
            let isOptimizeMode = false;
            // 如果是使用优化模式
            if (scrollXLoad || scrollYLoad || isAllOverflow) {
                // 如果是展开行,内联模式,不支持优化
                // 如果是方法合并,不支持优化
                // 如果固定列且配置式合并,不支持优化
                if ((expandColumn && expandOpts.mode !== 'fixed') || bodyMergeCoverFixed || spanMethod || footerSpanMethod) {
                    // 如果不支持优化模式
                }
                else {
                    isOptimizeMode = true;
                }
            }
            return isOptimizeMode;
        });
        const computeIsFooterRenderOptimize = computed(() => {
            const { spanMethod, footerSpanMethod, showFooterOverflow: allColumnFooterOverflow } = props;
            const { scrollXLoad } = reactData;
            let isOptimizeMode = false;
            // 如果是使用优化模式
            if (scrollXLoad && allColumnFooterOverflow) {
                if (spanMethod || footerSpanMethod) {
                    // 如果不支持优化模式
                }
                else {
                    isOptimizeMode = true;
                }
            }
            return isOptimizeMode;
        });
        const computeHeaderMenu = computed(() => {
            const menuOpts = computeMenuOpts.value;
            const headerOpts = menuOpts.header;
            return headerOpts && headerOpts.options ? headerOpts.options : [];
        });
        const computeBodyMenu = computed(() => {
            const menuOpts = computeMenuOpts.value;
            const bodyOpts = menuOpts.body;
            return bodyOpts && bodyOpts.options ? bodyOpts.options : [];
        });
        const computeFooterMenu = computed(() => {
            const menuOpts = computeMenuOpts.value;
            const footerOpts = menuOpts.footer;
            return footerOpts && footerOpts.options ? footerOpts.options : [];
        });
        const computeIsMenu = computed(() => {
            const isContentMenu = computeIsContentMenu.value;
            return isContentMenu;
        });
        const computeIsContentMenu = computed(() => {
            const menuOpts = computeMenuOpts.value;
            const headerMenu = computeHeaderMenu.value;
            const bodyMenu = computeBodyMenu.value;
            const footerMenu = computeFooterMenu.value;
            return !!(props.menuConfig && isEnableConf(menuOpts) && (headerMenu.length || bodyMenu.length || footerMenu.length));
        });
        const computeMenuList = computed(() => {
            const { ctxMenuStore } = reactData;
            const rest = [];
            ctxMenuStore.list.forEach((list) => {
                list.forEach((item) => {
                    rest.push(item);
                });
            });
            return rest;
        });
        const computeExportOpts = computed(() => {
            return Object.assign({}, getConfig().table.exportConfig, props.exportConfig);
        });
        const computeImportOpts = computed(() => {
            return Object.assign({}, getConfig().table.importConfig, props.importConfig);
        });
        const computePrintOpts = computed(() => {
            return Object.assign({}, getConfig().table.printConfig, props.printConfig);
        });
        const computeExpandOpts = computed(() => {
            return Object.assign({}, getConfig().table.expandConfig, props.expandConfig);
        });
        const computeTreeOpts = computed(() => {
            return Object.assign({}, getConfig().table.treeConfig, props.treeConfig);
        });
        const computeEmptyOpts = computed(() => {
            return Object.assign({}, getConfig().table.emptyRender, props.emptyRender);
        });
        const computeLoadingOpts = computed(() => {
            return Object.assign({}, getConfig().table.loadingConfig, props.loadingConfig);
        });
        const computeCellOffsetWidth = computed(() => {
            return props.border ? Math.max(2, Math.ceil(reactData.scrollbarWidth / reactData.tableColumn.length)) : 1;
        });
        const computeCustomOpts = computed(() => {
            return Object.assign({}, getConfig().table.customConfig, props.customConfig);
        });
        const computeCustomSimpleMode = computed(() => {
            const { minHeight, height } = props;
            const customOpts = computeCustomOpts.value;
            const { mode, popupOptions, placement } = customOpts;
            if (!placement || placement === 'top-left' || placement === 'top-right') {
                if (!(mode === 'modal' || mode === 'drawer')) {
                    const { mode } = popupOptions || {};
                    if (!mode || mode === 'auto') {
                        if (height || minHeight) {
                            return 'inside';
                        }
                        return 'outside';
                    }
                    if (mode) {
                        return mode;
                    }
                }
            }
            return '';
        });
        const computeTableStyle = computed(() => {
            const scrollbarOpts = computeScrollbarOpts.value;
            const { width, height } = scrollbarOpts;
            const tStys = {};
            if (width) {
                tStys['--vxe-ui-table-view-scrollbar-width'] = toCssUnit(width);
            }
            if (height) {
                tStys['--vxe-ui-table-view-scrollbar-height'] = toCssUnit(height);
            }
            return tStys;
        });
        const computeTableRowExpandedList = computed(() => {
            const { tableData, rowExpandedFlag, expandColumn, rowGroupExpandedFlag, treeExpandedFlag } = reactData;
            const { visibleDataRowIdData, rowExpandedMaps } = internalData;
            const expandList = [];
            if (tableData.length && expandColumn && rowExpandedFlag && rowGroupExpandedFlag && treeExpandedFlag) {
                XEUtils.each(rowExpandedMaps, (row, rowid) => {
                    if (visibleDataRowIdData[rowid]) {
                        expandList.push(row);
                    }
                });
            }
            return expandList;
        });
        const computeAutoWidthColumnList = computed(() => {
            const { visibleColumn } = internalData;
            const { tableColumn } = reactData;
            return tableColumn.length || visibleColumn.length ? visibleColumn.filter(column => column.width === 'auto' || column.minWidth === 'auto') : [];
        });
        const computeFixedColumnSize = computed(() => {
            const { tableColumn } = reactData;
            const { collectColumn } = internalData;
            let fixedSize = 0;
            // 只判断第一层
            if (tableColumn.length && collectColumn.length) {
                collectColumn.forEach((column) => {
                    if (column.renderFixed) {
                        fixedSize++;
                    }
                });
            }
            return fixedSize;
        });
        const computeIsMaxFixedColumn = computed(() => {
            const fixedColumnSize = computeFixedColumnSize.value;
            const columnOpts = computeColumnOpts.value;
            const { maxFixedSize } = columnOpts;
            if (maxFixedSize) {
                return fixedColumnSize >= maxFixedSize;
            }
            return false;
        });
        const computeKeepFields = computed(() => {
            const { tableFullColumn } = internalData;
            const { updateColFlag } = reactData;
            const editDirtyOpts = computeEditDirtyOpts.value;
            const { extraFields, includeFields, excludeFields } = editDirtyOpts;
            const kpFields = [];
            if (updateColFlag) {
                // 优先级 excludeFields > (includeFields || extraFields)
                const excludeFdMaps = {};
                if (excludeFields && excludeFields.length) {
                    excludeFields.forEach(field => {
                        excludeFdMaps[field] = 1;
                    });
                }
                if (includeFields && includeFields.length) {
                    return excludeFields && excludeFields.length ? includeFields.filter(field => !excludeFdMaps[field]) : includeFields;
                }
                const addFdMaps = {};
                if (extraFields && extraFields.length) {
                    extraFields.forEach(field => {
                        if (!addFdMaps[field]) {
                            addFdMaps[field] = 1;
                            kpFields.push(field);
                        }
                    });
                }
                for (let i = 0; i < tableFullColumn.length; i++) {
                    const column = tableFullColumn[i];
                    const { field, type, editRender, cellRender } = column;
                    if (field && !type && (editRender || cellRender) && !addFdMaps[field] && !excludeFdMaps[field]) {
                        addFdMaps[field] = 1;
                        kpFields.push(field);
                    }
                }
            }
            return kpFields;
        });
        const computeTableBorder = computed(() => {
            const { border } = props;
            if (border === true) {
                return 'full';
            }
            if (border) {
                return border;
            }
            return 'default';
        });
        const computeIsAllCheckboxDisabled = computed(() => {
            const { treeConfig } = props;
            const { tableData } = reactData;
            const { tableFullData } = internalData;
            const checkboxOpts = computeCheckboxOpts.value;
            const { strict, checkMethod } = checkboxOpts;
            if (strict) {
                if (tableData.length || tableFullData.length) {
                    if (checkMethod) {
                        if (treeConfig) {
                            // 暂时不支持树形结构
                        }
                        // 如果所有行都被禁用
                        return tableFullData.every((row) => !checkMethod({ $table: $xeTable, row }));
                    }
                    return false;
                }
                return true;
            }
            return false;
        });
        const computeVirtualScrollBars = computed(() => {
            const { overflowX, scrollXLoad, overflowY, scrollYLoad } = reactData;
            return {
                x: overflowX && scrollXLoad,
                y: overflowY && scrollYLoad
            };
        });
        const computeRowGroupFields = computed(() => {
            const rowGroupOpts = computeRowGroupOpts.value;
            return rowGroupOpts.groupFields;
        });
        const computeRowGroupColumns = computed(() => {
            const { rowGroupList } = reactData;
            const { fullColumnFieldData } = internalData;
            const rgColumns = [];
            rowGroupList.forEach(aggConf => {
                const colRest = fullColumnFieldData[aggConf.field];
                if (colRest) {
                    rgColumns.push(colRest.column);
                }
            });
            return rgColumns;
        });
        const computeAggFuncColumns = computed(() => {
            const { rowGroupList, tableColumn } = reactData;
            if (rowGroupList.length) {
                return tableColumn.filter(column => column.aggFunc);
            }
            return [];
        });
        const combineTabsResizeFlag = computed(() => {
            return $xeTabs ? $xeTabs.reactData.resizeFlag : null;
        });
        const combineModalResizeFlag = computed(() => {
            return $xeModal ? $xeModal.reactData.resizeFlag : null;
        });
        const combineSplitterResizeFlag = computed(() => {
            return $xeSplitter ? $xeSplitter.reactData.resizeFlag : null;
        });
        const refMaps = {
            refElem,
            refTooltip,
            refValidTooltip,
            refTableFilter,
            refTableCustom,
            refTableMenu,
            refTableHeader,
            refTableBody,
            refTableFooter,
            refTableLeftHeader,
            refTableLeftBody,
            refTableLeftFooter,
            refTableRightHeader,
            refTableRightBody,
            refTableRightFooter,
            refLeftContainer,
            refRightContainer,
            refColResizeBar,
            refRowResizeBar,
            refCustomContainerElem,
            refScrollXVirtualElem,
            refScrollYVirtualElem,
            refScrollXHandleElem,
            refScrollYHandleElem,
            refScrollXSpaceElem,
            refScrollYSpaceElem
        };
        const computeMaps = {
            computeSize,
            computeTableId,
            computeValidOpts,
            computeRowField,
            computeVirtualXOpts,
            computeVirtualYOpts,
            computeScrollbarOpts,
            computeScrollbarXOpts,
            computeScrollbarYOpts,
            computeScrollbarXToTop,
            computeScrollbarYToLeft,
            computeColumnOpts,
            computeCurrentColumnOpts,
            computeScrollXThreshold,
            computeScrollYThreshold,
            computeRowHeightMaps,
            computeDefaultRowHeight,
            computeCellOpts,
            computeHeaderCellOpts,
            computeFooterCellOpts,
            computeRowOpts,
            computeAggregateOpts,
            computeAggregateAccuracyOpts,
            computeRowGroupOpts,
            computeCurrentRowOpts,
            computeRowDragOpts,
            computeColumnDragOpts,
            computeResizeOpts,
            computeResizableOpts,
            computeSeqOpts,
            computeRadioOpts,
            computeCheckboxOpts,
            computeTooltipOpts,
            computeHeaderTooltipOpts,
            computeFooterTooltipOpts,
            computeEditOpts,
            computeEditDirtyOpts,
            computeSortOpts,
            computeFilterOpts,
            computeFloatingFilterOpts,
            computeMouseOpts,
            computeAreaOpts,
            computeKeyboardOpts,
            computeClipOpts,
            computeFnrOpts,
            computeHeaderMenu,
            computeBodyMenu,
            computeFooterMenu,
            computeIsMenu,
            computeIsContentMenu,
            computeMenuList,
            computeMenuOpts,
            computeExportOpts,
            computeImportOpts,
            computePrintOpts,
            computeExpandOpts,
            computeTreeOpts,
            computeEmptyOpts,
            computeLoadingOpts,
            computeCellOffsetWidth,
            computeCustomOpts,
            computeCustomSimpleMode,
            computeLeftFixedWidth,
            computeRightFixedWidth,
            computeBodyMergeCoverFixed,
            computeFixedColumnSize,
            computeIsMaxFixedColumn,
            computeKeepFields,
            computeIsAllCheckboxDisabled,
            computeIsHeaderRenderOptimize,
            computeIsBodyRenderOptimize,
            computeIsFooterRenderOptimize,
            computeVirtualScrollBars,
            computeRowGroupFields,
            computeRowGroupColumns,
            computeAggFuncColumns,
            computeUndoRedoHistoryOpts,
            computeFNROpts,
            computeSXOpts,
            computeSYOpts
        };
        const $xeTable = {
            xID,
            props: props,
            context,
            reactData,
            internalData,
            getRefMaps: () => refMaps,
            getComputeMaps: () => computeMaps,
            xeGrid: $xeGrid,
            xeGantt: $xeGantt,
            // 已废弃
            xegrid: $xeGrid
        };
        const eqCellValue = (newRow, oldRow, field) => {
            const val1 = XEUtils.get(newRow, field);
            const val2 = XEUtils.get(oldRow, field);
            let result = false;
            if (eqEmptyValue(val1) && eqEmptyValue(val2)) {
                result = true;
            }
            else if (XEUtils.isString(val1) || XEUtils.isNumber(val1)) {
                result = ('' + val1) === ('' + val2);
            }
            else {
                result = XEUtils.isEqual(val1, val2);
            }
            return { newValue: val1, oldValue: val2, result };
        };
        const handleKeyField = () => {
            const keyField = computeRowField.value;
            internalData.currKeyField = keyField;
            internalData.isCurrDeepKey = hasDeepKey(keyField);
        };
        const getNextSortOrder = (column) => {
            const sortOpts = computeSortOpts.value;
            const { orders = [] } = sortOpts;
            const currOrder = column.order || null;
            const oIndex = orders.indexOf(currOrder) + 1;
            return orders[oIndex < orders.length ? oIndex : 0];
        };
        const getCustomStorageMap = (id) => {
            const version = getConfig().version;
            const rest = XEUtils.toStringJSON(localStorage.getItem(customStorageKey) || '');
            const maps = rest && rest._v === version ? rest : { _v: version };
            return (id ? maps[id] : maps) || {};
        };
        const setCustomStorageMap = (id, data) => {
            const version = getConfig().version;
            const maps = getCustomStorageMap();
            maps[id] = data || undefined;
            maps._v = version;
            localStorage.setItem(customStorageKey, XEUtils.toJSONString(maps));
        };
        const getRecoverRowMaps = (keyMaps) => {
            const { fullAllDataRowIdData } = internalData;
            const restKeys = {};
            XEUtils.each(keyMaps, (row, rowid) => {
                if (fullAllDataRowIdData[rowid]) {
                    restKeys[rowid] = row;
                }
            });
            return restKeys;
        };
        const handleReserveRow = (reserveRowMap) => {
            const { fullDataRowIdData } = internalData;
            const reserveList = [];
            XEUtils.each(reserveRowMap, (item, rowid) => {
                if (fullDataRowIdData[rowid] && $xeTable.findRowIndexOf(reserveList, fullDataRowIdData[rowid].row) === -1) {
                    reserveList.push(fullDataRowIdData[rowid].row);
                }
            });
            return reserveList;
        };
        const handleVirtualXVisible = () => {
            const { isScrollXBig, scrollXWidth } = reactData;
            const { elemStore, visibleColumn, fullColumnIdData } = internalData;
            const leftFixedWidth = computeLeftFixedWidth.value;
            const rightFixedWidth = computeRightFixedWidth.value;
            const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
            if (bodyScrollElem) {
                const clientWidth = bodyScrollElem.clientWidth;
                let scrollLeft = bodyScrollElem.scrollLeft;
                if (isScrollXBig) {
                    scrollLeft = Math.ceil((scrollXWidth - clientWidth) * Math.min(1, (scrollLeft / (maxXWidth - clientWidth))));
                }
                const startLeft = scrollLeft + leftFixedWidth;
                const endLeft = scrollLeft + clientWidth - rightFixedWidth;
                let leftIndex = 0;
                let rightIndex = visibleColumn.length;
                while (leftIndex < rightIndex) {
                    const cIndex = Math.floor((leftIndex + rightIndex) / 2);
                    const column = visibleColumn[cIndex];
                    const colid = column.id;
                    const colRest = fullColumnIdData[colid] || {};
                    if (colRest.oLeft <= startLeft) {
                        leftIndex = cIndex + 1;
                    }
                    else {
                        rightIndex = cIndex;
                    }
                }
                let visibleSize = 0;
                const toVisibleIndex = leftIndex === visibleColumn.length ? leftIndex : Math.max(0, leftIndex < visibleColumn.length ? leftIndex - 2 : 0);
                for (let cIndex = toVisibleIndex, cLen = visibleColumn.length; cIndex < cLen; cIndex++) {
                    const column = visibleColumn[cIndex];
                    const colid = column.id;
                    const colRest = fullColumnIdData[colid] || {};
                    visibleSize++;
                    if (colRest.oLeft > endLeft || visibleSize >= 60) {
                        break;
                    }
                }
                return { toVisibleIndex: Math.max(0, toVisibleIndex), visibleSize: Math.max(1, visibleSize) };
            }
            return { toVisibleIndex: 0, visibleSize: 6 };
        };
        const calcVarRowHeightConfig = (sizeKey, sizeEl) => {
            const { rowHeightStore } = reactData;
            if (sizeEl && sizeEl.clientHeight) {
                rowHeightStore[sizeKey] = sizeEl.clientHeight;
            }
        };
        const computeRowHeight = () => {
            const { isAllOverflow } = reactData;
            const tableHeader = refTableHeader.value;
            const tableBody = refTableBody.value;
            const tableBodyElem = tableBody ? tableBody.$el : null;
            const defaultRowHeight = computeDefaultRowHeight.value;
            let rowHeight = 0;
            if (isAllOverflow) {
                if (tableBodyElem) {
                    const tableHeaderElem = tableHeader ? tableHeader.$el : null;
                    let firstTrElem;
                    firstTrElem = tableBodyElem.querySelector('tr');
                    if (!firstTrElem && tableHeaderElem) {
                        firstTrElem = tableHeaderElem.querySelector('tr');
                    }
                    if (firstTrElem) {
                        rowHeight = firstTrElem.clientHeight;
                    }
                }
                if (!rowHeight) {
                    rowHeight = defaultRowHeight;
                }
            }
            else {
                rowHeight = defaultRowHeight;
            }
            // 最低支持 18px 行高
            return Math.max(18, rowHeight);
        };
        const handleVirtualYVisible = () => {
            const { isAllOverflow, expandColumn, isScrollYBig, scrollYHeight } = reactData;
            const { elemStore, isResizeCellHeight, afterFullData, fullAllDataRowIdData } = internalData;
            const rowOpts = computeRowOpts.value;
            const cellOpts = computeCellOpts.value;
            const defaultRowHeight = computeDefaultRowHeight.value;
            const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
            if (bodyScrollElem) {
                const clientHeight = bodyScrollElem.clientHeight;
                let scrollTop = bodyScrollElem.scrollTop;
                if (isScrollYBig) {
                    scrollTop = Math.ceil((scrollYHeight - clientHeight) * Math.min(1, (scrollTop / (maxYHeight - clientHeight))));
                }
                const startTop = scrollTop;
                const endTop = scrollTop + clientHeight;
                let toVisibleIndex = -1;
                let visibleSize = 0;
                const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height;
                if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
                    toVisibleIndex = Math.floor(startTop / defaultRowHeight) - 1;
                    visibleSize = Math.ceil(clientHeight / defaultRowHeight) + 1;
                }
                else {
                    const { handleGetRowId } = createHandleGetRowId($xeTable);
                    let leftIndex = 0;
                    let rightIndex = afterFullData.length;
                    while (leftIndex < rightIndex) {
                        const rIndex = Math.floor((leftIndex + rightIndex) / 2);
                        const row = afterFullData[rIndex];
                        const rowid = handleGetRowId(row);
                        const rowRest = fullAllDataRowIdData[rowid] || {};
                        if (rowRest.oTop <= startTop) {
                            leftIndex = rIndex + 1;
                        }
                        else {
                            rightIndex = rIndex;
                        }
                    }
                    toVisibleIndex = leftIndex === afterFullData.length ? leftIndex : Math.max(0, leftIndex < afterFullData.length ? leftIndex - 2 : 0);
                    for (let rIndex = toVisibleIndex, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
                        const row = afterFullData[rIndex];
                        const rowid = handleGetRowId(row);
                        const rowRest = fullAllDataRowIdData[rowid] || {};
                        visibleSize++;
                        if (rowRest.oTop > endTop || visibleSize >= 100) {
                            break;
                        }
                    }
                }
                return { toVisibleIndex: Math.max(0, toVisibleIndex), visibleSize: Math.max(6, visibleSize) };
            }
            return { toVisibleIndex: 0, visibleSize: 6 };
        };
        const calculateMergerOffsetIndex = (list, mergeMaps, offsetItem, type) => {
            const mKey = `${offsetItem.startIndex}:${offsetItem.endIndex}`;
            const mObj = mergeMaps[mKey];
            // 缓存
            if (mObj) {
                offsetItem.startIndex = mObj.startIndex;
                offsetItem.endIndex = mObj.endIndex;
            }
            else {
                for (let mcIndex = 0, len = list.length; mcIndex < len; mcIndex++) {
                    const mergeItem = list[mcIndex];
                    const { startIndex, endIndex } = offsetItem;
                    const mergeStartIndex = mergeItem[type];
                    const mergeSpanNumber = mergeItem[type + 'span'];
                    const mergeEndIndex = mergeStartIndex + mergeSpanNumber;
                    if (mergeStartIndex < startIndex && startIndex < mergeEndIndex) {
                        offsetItem.startIndex = mergeStartIndex;
                    }
                    if (mergeStartIndex < endIndex && endIndex < mergeEndIndex) {
                        offsetItem.endIndex = mergeEndIndex;
                    }
                    if (offsetItem.startIndex !== startIndex || offsetItem.endIndex !== endIndex) {
                        mcIndex = -1;
                    }
                }
                mergeMaps[mKey] = offsetItem;
            }
        };
        function buildMergeData(mergeConfigs) {
            const mergeMaps = {};
            const mergeRowMaps = {};
            const mergeColMaps = {};
            if (mergeConfigs && mergeConfigs.length) {
                for (let mIndex = 0; mIndex < mergeConfigs.length; mIndex++) {
                    const { row: _rowIndex, col: _columnIndex, rowspan: mergeRowspan, colspan: mergeColspan } = mergeConfigs[mIndex];
                    for (let i = 0; i < mergeRowspan; i++) {
                        const currRIndex = _rowIndex + i;
                        for (let j = 0; j < mergeColspan; j++) {
                            const currCIndex = _columnIndex + j;
                            mergeMaps[`${currRIndex}:${currCIndex}`] = !i && !j
                                ? {
                                    rowspan: mergeRowspan,
                                    colspan: mergeColspan
                                }
                                : {
                                    rowspan: 0,
                                    colspan: 0
                                };
                        }
                    }
                }
            }
            return { mergeMaps, mergeRowMaps, mergeColMaps };
        }
        const handleUpdateMergeBodyCells = (merges) => {
            internalData.mergeBodyList = [];
            internalData.mergeBodyMaps = {};
            internalData.mergeBodyCellMaps = {};
            internalData.mergeBodyRowMaps = {};
            internalData.mergeBodyColMaps = {};
            $xeTable.setMergeCells(merges);
        };
        const handleBodyMerge = (merges) => {
            const { fullAllDataRowIdData, fullColumnIdData, visibleColumn, afterFullData, mergeBodyList, mergeBodyMaps } = internalData;
            if (merges) {
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                if (!XEUtils.isArray(merges)) {
                    merges = [merges];
                }
                merges.forEach((item) => {
                    let { row: margeRow, col: margeCol, rowspan, colspan } = item;
                    let mergeRowIndex = -1;
                    let mergeColumnIndex = -1;
                    if (XEUtils.isNumber(margeRow)) {
                        mergeRowIndex = margeRow;
                    }
                    else {
                        const rowid = margeRow ? handleGetRowId(margeRow) : null;
                        const rowRest = rowid ? fullAllDataRowIdData[rowid] : null;
                        if (rowRest) {
                            mergeRowIndex = rowRest._index;
                        }
                    }
                    if (XEUtils.isNumber(margeCol)) {
                        mergeColumnIndex = margeCol;
                    }
                    else {
                        const colid = margeCol ? margeCol.id : null;
                        const colRest = colid ? fullColumnIdData[colid] : null;
                        if (colRest) {
                            mergeColumnIndex = colRest._index;
                        }
                    }
                    if (mergeRowIndex > -1 && mergeColumnIndex > -1 && (rowspan || colspan)) {
                        rowspan = XEUtils.toNumber(rowspan) || 1;
                        colspan = XEUtils.toNumber(colspan) || 1;
                        if (rowspan > 1 || colspan > 1) {
                            const row = afterFullData[mergeRowIndex];
                            const column = visibleColumn[mergeColumnIndex];
                            let mergeItem = mergeBodyMaps[`${mergeRowIndex}:${mergeColumnIndex}`];
                            if (mergeItem) {
                                mergeItem.rowspan = rowspan;
                                mergeItem.colspan = colspan;
                                mergeItem._rowspan = rowspan;
                                mergeItem._colspan = colspan;
                            }
                            else {
                                mergeItem = {
                                    row: mergeRowIndex,
                                    col: mergeColumnIndex,
                                    rowspan,
                                    colspan,
                                    _row: row,
                                    _col: column,
                                    _rowspan: rowspan,
                                    _colspan: colspan
                                };
                                mergeBodyMaps[`${mergeRowIndex}:${mergeColumnIndex}`] = mergeItem;
                                mergeBodyList.push(mergeItem);
                            }
                        }
                    }
                });
            }
        };
        const removeBodyMerges = (merges) => {
            const { mergeBodyList, fullColumnIdData, fullAllDataRowIdData, mergeBodyMaps } = internalData;
            const rest = [];
            if (merges) {
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                if (!XEUtils.isArray(merges)) {
                    merges = [merges];
                }
                merges.forEach((item) => {
                    const { row: margeRow, col: margeCol } = item;
                    let mergeRowIndex = -1;
                    let mergeColumnIndex = -1;
                    if (XEUtils.isNumber(margeRow)) {
                        mergeRowIndex = margeRow;
                    }
                    else {
                        const rowid = margeRow ? handleGetRowId(margeRow) : null;
                        const rowRest = rowid ? fullAllDataRowIdData[rowid] : null;
                        if (rowRest) {
                            mergeRowIndex = rowRest._index;
                        }
                    }
                    if (XEUtils.isNumber(margeCol)) {
                        mergeColumnIndex = margeCol;
                    }
                    else {
                        const colid = margeCol ? margeCol.id : null;
                        const colRest = colid ? fullColumnIdData[colid] : null;
                        if (colRest) {
                            mergeColumnIndex = colRest._index;
                        }
                    }
                    const mcIndex = XEUtils.findIndexOf(mergeBodyList, item => item.row === mergeRowIndex && item.col === mergeColumnIndex);
                    if (mcIndex > -1) {
                        const rItems = mergeBodyList.splice(mcIndex, 1);
                        const item = rItems[0];
                        if (item) {
                            rest.push(rItems[0]);
                            if (mergeBodyMaps[`${mergeRowIndex}:${mergeColumnIndex}`]) {
                                delete mergeBodyMaps[`${mergeRowIndex}:${mergeColumnIndex}`];
                            }
                        }
                    }
                });
            }
            return rest;
        };
        const handleUpdateMergeHeaderCells = (merges) => {
            internalData.mergeHeaderList = [];
            internalData.mergeHeaderMaps = {};
            internalData.mergeHeaderCellMaps = {};
            internalData.mergeHeaderRowMaps = {};
            internalData.mergeBodyColMaps = {};
            $xeTable.setMergeHeaderCells(merges);
        };
        const handleHeaderMerge = (merges) => {
            const { showCustomHeader } = props;
            const { footerTableData } = reactData;
            const { mergeHeaderList, mergeHeaderMaps, fullColumnIdData } = internalData;
            if (merges) {
                const { visibleColumn } = internalData;
                if (!XEUtils.isArray(merges)) {
                    merges = [merges];
                }
                merges.forEach((item) => {
                    let { row: margeRow, col: margeCol, rowspan, colspan } = item;
                    const mergeRowIndex = XEUtils.isNumber(margeRow) ? margeRow : -1;
                    let mergeColumnIndex = -1;
                    if (XEUtils.isNumber(margeCol)) {
                        mergeColumnIndex = margeCol;
                    }
                    else {
                        const colid = margeCol ? margeCol.id : null;
                        const colRest = colid ? fullColumnIdData[colid] : null;
                        if (colRest) {
                            mergeColumnIndex = colRest._index;
                        }
                    }
                    if (mergeRowIndex > -1 && mergeColumnIndex > -1 && (rowspan || colspan)) {
                        rowspan = XEUtils.toNumber(rowspan) || 1;
                        colspan = XEUtils.toNumber(colspan) || 1;
                        if (!showCustomHeader && rowspan > 1) {
                            errLog('vxe.error.notSupportProp', ['[table] show-custom-header=false', `rowspan=${rowspan}`, 'rowspan=1']);
                            return;
                        }
                        if (rowspan > 1 || colspan > 1) {
                            const row = footerTableData[mergeRowIndex];
                            const column = visibleColumn[mergeColumnIndex];
                            let mergeItem = mergeHeaderMaps[`${mergeRowIndex}:${mergeColumnIndex}`];
                            if (mergeItem) {
                                mergeItem.rowspan = rowspan;
                                mergeItem.colspan = colspan;
                                mergeItem._rowspan = rowspan;
                                mergeItem._colspan = colspan;
                            }
                            else {
                                mergeItem = {
                                    row: mergeRowIndex,
                                    col: mergeColumnIndex,
                                    rowspan,
                                    colspan,
                                    _row: row,
                                    _col: column,
                                    _rowspan: rowspan,
                                    _colspan: colspan
                                };
                                mergeHeaderMaps[`${mergeRowIndex}:${mergeColumnIndex}`] = mergeItem;
                                mergeHeaderList.push(mergeItem);
                            }
                        }
                    }
                });
            }
        };
        const removeHeaderMerges = (merges) => {
            const { mergeHeaderList, fullColumnIdData, mergeHeaderMaps } = internalData;
            const rest = [];
            if (merges) {
                if (!XEUtils.isArray(merges)) {
                    merges = [merges];
                }
                merges.forEach((item) => {
                    const { row: margeRow, col: margeCol } = item;
                    const mergeRowIndex = XEUtils.isNumber(margeRow) ? margeRow : -1;
                    let mergeColumnIndex = -1;
                    if (XEUtils.isNumber(margeCol)) {
                        mergeColumnIndex = margeCol;
                    }
                    else {
                        const colid = margeCol ? margeCol.id : null;
                        const colRest = colid ? fullColumnIdData[colid] : null;
                        if (colRest) {
                            mergeColumnIndex = colRest._index;
                        }
                    }
                    const mcIndex = XEUtils.findIndexOf(mergeHeaderList, item => item.row === mergeRowIndex && item.col === mergeColumnIndex);
                    if (mcIndex > -1) {
                        const rItems = mergeHeaderList.splice(mcIndex, 1);
                        const item = rItems[0];
                        if (item) {
                            rest.push(item);
                            if (mergeHeaderMaps[`${mergeRowIndex}:${mergeColumnIndex}`]) {
                                delete mergeHeaderMaps[`${mergeRowIndex}:${mergeColumnIndex}`];
                            }
                        }
                    }
                });
            }
            return rest;
        };
        const handleUpdateMergeFooterCells = (merges) => {
            internalData.mergeFooterList = [];
            internalData.mergeFooterMaps = {};
            internalData.mergeFooterCellMaps = {};
            internalData.mergeFooterRowMaps = {};
            internalData.mergeFooterColMaps = {};
            $xeTable.setMergeFooterCells(merges);
        };
        const handleFooterMerge = (merges) => {
            const { footerTableData } = reactData;
            const { mergeFooterList, mergeFooterMaps, fullColumnIdData } = internalData;
            if (merges) {
                const { visibleColumn } = internalData;
                if (!XEUtils.isArray(merges)) {
                    merges = [merges];
                }
                merges.forEach((item) => {
                    let { row: margeRow, col: margeCol, rowspan, colspan } = item;
                    const mergeRowIndex = XEUtils.isNumber(margeRow) ? margeRow : -1;
                    let mergeColumnIndex = -1;
                    if (XEUtils.isNumber(margeCol)) {
                        mergeColumnIndex = margeCol;
                    }
                    else {
                        const colid = margeCol ? margeCol.id : null;
                        const colRest = colid ? fullColumnIdData[colid] : null;
                        if (colRest) {
                            mergeColumnIndex = colRest._index;
                        }
                    }
                    if (mergeRowIndex > -1 && mergeColumnIndex > -1 && (rowspan || colspan)) {
                        rowspan = XEUtils.toNumber(rowspan) || 1;
                        colspan = XEUtils.toNumber(colspan) || 1;
                        if (rowspan > 1 || colspan > 1) {
                            const row = footerTableData[mergeRowIndex];
                            const column = visibleColumn[mergeColumnIndex];
                            let mergeItem = mergeFooterMaps[`${mergeRowIndex}:${mergeColumnIndex}`];
                            if (mergeItem) {
                                mergeItem.rowspan = rowspan;
                                mergeItem.colspan = colspan;
                                mergeItem._rowspan = rowspan;
                                mergeItem._colspan = colspan;
                            }
                            else {
                                mergeItem = {
                                    row: mergeRowIndex,
                                    col: mergeColumnIndex,
                                    rowspan,
                                    colspan,
                                    _row: row,
                                    _col: column,
                                    _rowspan: rowspan,
                                    _colspan: colspan
                                };
                                mergeFooterMaps[`${mergeRowIndex}:${mergeColumnIndex}`] = mergeItem;
                                mergeFooterList.push(mergeItem);
                            }
                        }
                    }
                });
            }
        };
        const removeFooterMerges = (merges) => {
            const { mergeFooterList, fullColumnIdData, mergeFooterMaps } = internalData;
            const rest = [];
            if (merges) {
                if (!XEUtils.isArray(merges)) {
                    merges = [merges];
                }
                merges.forEach((item) => {
                    const { row: margeRow, col: margeCol } = item;
                    const mergeRowIndex = XEUtils.isNumber(margeRow) ? margeRow : -1;
                    let mergeColumnIndex = -1;
                    if (XEUtils.isNumber(margeCol)) {
                        mergeColumnIndex = margeCol;
                    }
                    else {
                        const colid = margeCol ? margeCol.id : null;
                        const colRest = colid ? fullColumnIdData[colid] : null;
                        if (colRest) {
                            mergeColumnIndex = colRest._index;
                        }
                    }
                    const mcIndex = XEUtils.findIndexOf(mergeFooterList, item => item.row === mergeRowIndex && item.col === mergeColumnIndex);
                    if (mcIndex > -1) {
                        const rItems = mergeFooterList.splice(mcIndex, 1);
                        const item = rItems[0];
                        if (item) {
                            rest.push(item);
                            if (mergeFooterMaps[`${mergeRowIndex}:${mergeColumnIndex}`]) {
                                delete mergeFooterMaps[`${mergeRowIndex}:${mergeColumnIndex}`];
                            }
                        }
                    }
                });
            }
            return rest;
        };
        const handleSortEvent = (evnt, sortConfs, isUpdate) => {
            const { tableFullColumn } = internalData;
            const sortOpts = computeSortOpts.value;
            const { multiple, remote, orders } = sortOpts;
            if (!XEUtils.isArray(sortConfs)) {
                sortConfs = [sortConfs];
            }
            if (sortConfs && sortConfs.length) {
                const orderActiveMaps = {};
                if (!multiple) {
                    sortConfs = [sortConfs[0]];
                    tableFullColumn.forEach((column) => {
                        if (column.order) {
                            orderActiveMaps[column.id] = column;
                        }
                    });
                }
                const sortColMpps = {};
                let firstColumn = null;
                sortConfs.forEach((confs, index) => {
                    let { field, order } = confs;
                    let column = field;
                    if (XEUtils.isString(field)) {
                        column = $xeTable.getColumnByField(field);
                    }
                    if (!firstColumn) {
                        firstColumn = column;
                    }
                    if (column && column.sortable) {
                        if (orders && orders.indexOf(order) === -1) {
                            order = getNextSortOrder(column);
                        }
                        if (column.order !== order) {
                            column.order = order;
                        }
                        column.sortTime = Date.now() + index;
                        sortColMpps[column.id] = column;
                    }
                });
                if (!multiple) {
                    XEUtils.each(orderActiveMaps, (oaCol, oaId) => {
                        if (!sortColMpps[oaId]) {
                            oaCol.order = null;
                        }
                    });
                }
                if (isUpdate) {
                    if (!remote) {
                        $xeTable.handleTableData(true);
                    }
                }
                if (evnt) {
                    $xeTable.handleColumnSortEvent(evnt, firstColumn);
                }
                return nextTick().then(() => {
                    updateRowOffsetTop();
                    $xeTable.updateCellAreas();
                    return updateStyle();
                });
            }
            return nextTick();
        };
        const clearAllSort = () => {
            const { tableFullColumn } = internalData;
            tableFullColumn.forEach((column) => {
                column.order = null;
            });
        };
        const calcTableHeight = (key) => {
            const { editConfig, editRules } = props;
            const { parentHeight, tableColumn } = reactData;
            let val = props[key];
            if (key === 'minHeight') {
                const defMinHeight = getConfig().table.minHeight;
                if (XEUtils.eqNull(val)) {
                    if (eqEmptyValue(defMinHeight)) {
                        if (!tableColumn.length) {
                            // 如果全部列被隐藏
                            val = 40;
                        }
                        else if (editRules && isEnableConf(editConfig)) {
                            // 编辑模式默认最小高度
                            val = 144;
                        }
                    }
                    else {
                        val = defMinHeight;
                    }
                }
            }
            let num = 0;
            if (val) {
                if (val === '100%' || val === 'auto') {
                    num = parentHeight;
                }
                else {
                    const excludeHeight = $xeTable.getExcludeHeight();
                    if (isScale(val)) {
                        num = Math.floor((XEUtils.toInteger(val) || 1) / 100 * parentHeight);
                    }
                    else {
                        num = XEUtils.toNumber(val);
                    }
                    num = Math.max(40, num - excludeHeight);
                }
            }
            return num;
        };
        const handleCustomRestore = (storeData) => {
            const { aggregateConfig, rowGroupConfig } = props;
            const { collectColumn } = internalData;
            const { isCustomAlign, isCustomHeaderAlign, isCustomFooterAlign, isCustomResizable, isCustomVisible, isCustomFixed, isCustomSort, isCustomAggGroup, isCustomAggFunc, isCustomPager } = handleCustomStoreConfig($xeTable);
            let { alignData, headerAlignData, footerAlignData, resizableData, sortData, visibleData, fixedData, aggGroupData, aggFuncData, pagerData } = storeData;
            // 处理还原
            if ((isCustomAlign && alignData) ||
                (isCustomHeaderAlign && headerAlignData) ||
                (isCustomFooterAlign && footerAlignData) ||
                (isCustomResizable && resizableData) ||
                (isCustomSort && sortData) ||
                (isCustomVisible && visibleData) ||
                (isCustomFixed && fixedData) ||
                (isCustomAggGroup && aggGroupData) ||
                (isCustomAggFunc && aggFuncData) ||
                (isCustomPager && pagerData && $xeGGWrapper)) {
                const sortColMaps = {};
                if (isCustomSort && sortData) {
                    // 转换兼容老版本数据,即将废弃兼容
                    if (!XEUtils.isArray(sortData)) {
                        const sortRests = [];
                        XEUtils.each(sortData, (index, colKey) => {
                            sortRests.push({ key: colKey, index });
                        });
                        sortData = XEUtils.orderBy(sortRests, { field: 'index', order: 'asc' }).map(item => ({ k: item.key }));
                    }
                    let colNum = 1;
                    XEUtils.eachTree(sortData, (sObj, index, sOjs, path, pSObj) => {
                        sortColMaps[sObj.k] = {
                            key: sObj.k,
                            sNum: colNum++,
                            pKey: pSObj ? pSObj.k : null
                        };
                    }, { children: 'c' });
                }
                const colKeyMaps = {};
                const allCols = [];
                const aggGroupConfs = [];
                XEUtils.eachTree(collectColumn, (column, index, items, path, parentColumn) => {
                    const colKey = column.getKey();
                    // 支持一级
                    if (!parentColumn) {
                        if (isCustomFixed && fixedData && fixedData[colKey] !== undefined) {
                            column.fixed = fixedData[colKey];
                        }
                    }
                    if (isCustomResizable && resizableData && XEUtils.isNumber(resizableData[colKey])) {
                        column.resizeWidth = resizableData[colKey];
                    }
                    if (isCustomVisible && visibleData && XEUtils.isBoolean(visibleData[colKey])) {
                        column.visible = visibleData[colKey];
                    }
                    if (isCustomAggFunc && aggFuncData && (aggregateConfig || rowGroupConfig) && aggFuncData[colKey]) {
                        column.aggFunc = aggFuncData[colKey];
                    }
                    if (isCustomAggGroup && aggGroupData && aggGroupData[colKey]) {
                        aggGroupConfs.push({ field: column.field });
                    }
                    colKeyMaps[colKey] = column;
                    allCols.push(column);
                });
                if ((aggregateConfig || rowGroupConfig) && aggGroupConfs.length) {
                    const groupRest = handleGroupData(internalData.tableFullData, aggGroupConfs);
                    internalData.tableFullTreeData = [];
                    internalData.tableFullGroupData = groupRest.treeData;
                    reactData.isRowGroupStatus = true;
                    reactData.rowGroupList = aggGroupConfs;
                    $xeTable.cacheRowMap(false);
                }
                // 如果自定义了顺序
                if (isCustomSort && sortData) {
                    allCols.forEach(column => {
                        const colKey = column.getKey();
                        const scItem = sortColMaps[colKey];
                        if (scItem) {
                            const parentColumn = scItem.pKey ? colKeyMaps[scItem.pKey] : null;
                            column.parentId = parentColumn ? parentColumn.id : null;
                            column.renderSortNumber = scItem.sNum;
                        }
                    });
                    const newCollectCols = XEUtils.toArrayTree(XEUtils.orderBy(allCols, 'renderSortNumber'), { key: 'id', parentKey: 'parentId', children: 'children' });
                    internalData.collectColumn = newCollectCols;
                    internalData.tableFullColumn = getColumnList(newCollectCols);
                    reactData.updateColFlag++;
                }
                reactData.isCustomStatus = true;
            }
            else {
                reactData.isCustomStatus = false;
            }
        };
        /**
         * 还原自定义列操作状态
         */
        const restoreCustomStorage = () => {
            const { customConfig } = props;
            const tableId = computeTableId.value;
            const customOpts = computeCustomOpts.value;
            const { storage, restoreStore } = customOpts;
            const { isCustomAlign, isCustomHeaderAlign, isCustomFooterAlign, isCustomResizable, isCustomVisible, isCustomFixed, isCustomSort, isCustomAggGroup, isCustomAggFunc } = handleCustomStoreConfig($xeTable);
            if (storage &&
                (customConfig ? isEnableConf(customOpts) : customOpts.enabled) &&
                (isCustomAlign ||
                    isCustomHeaderAlign ||
                    isCustomFooterAlign ||
                    isCustomResizable ||
                    isCustomVisible ||
                    isCustomFixed ||
                    isCustomSort ||
                    isCustomAggGroup ||
                    isCustomAggFunc)) {
                if (!tableId) {
                    errLog('vxe.error.reqProp', ['id']);
                    return;
                }
                const storeData = getCustomStorageMap(tableId);
                if (restoreStore) {
                    return Promise.resolve(restoreStore({ $table: $xeTable, id: tableId, type: 'restore', storeData })).then(storeData => {
                        if (!storeData) {
                            return;
                        }
                        return handleCustomRestore(storeData);
                    }).catch(e => e);
                }
                else {
                    return handleCustomRestore(storeData);
                }
            }
        };
        const updateColumnAllOverflow = () => {
            const { showOverflow } = props;
            const { isGroup } = reactData;
            const { fullAllDataRowIdData, tableFullColumn, collectColumn } = internalData;
            let isAllOverflow = !!showOverflow;
            const handleFunc = (column) => {
                if (isAllOverflow && column.showOverflow === false) {
                    isAllOverflow = false;
                }
            };
            if (isGroup) {
                XEUtils.eachTree(collectColumn, handleFunc);
            }
            else {
                tableFullColumn.forEach(handleFunc);
            }
            XEUtils.each(fullAllDataRowIdData, (rowRest) => {
                rowRest.height = 0;
            });
            reactData.isAllOverflow = isAllOverflow;
        };
        /**
         * 更新数据列的 Map
         * 牺牲数据组装的耗时,用来换取使用过程中的流畅
         */
        const cacheColumnMap = () => {
            const { treeConfig, showOverflow } = props;
            const { tableFullColumn, collectColumn } = internalData;
            const fullColIdData = internalData.fullColumnIdData = {};
            const fullColFieldData = internalData.fullColumnFieldData = {};
            const mouseOpts = computeMouseOpts.value;
            const expandOpts = computeExpandOpts.value;
            const columnOpts = computeColumnOpts.value;
            const columnDragOpts = computeColumnDragOpts.value;
            const virtualYOpts = computeVirtualYOpts.value;
            const { isCrossDrag, isSelfToChildDrag } = columnDragOpts;
            const customOpts = computeCustomOpts.value;
            const treeOpts = computeTreeOpts.value;
            const { storage } = customOpts;
            const rowOpts = computeRowOpts.value;
            const isGroup = collectColumn.some(hasChildrenList);
            let isAllOverflow = !!showOverflow;
            let rowGroupColumn;
            let expandColumn;
            let treeNodeColumn;
            let checkboxColumn;
            let radioColumn;
            let htmlColumn;
            let hasFixed;
            const handleFunc = (column, index, items, path, parentColumn) => {
                const { id: colid, field, fixed, type, treeNode, rowGroupNode } = column;
                const rest = { $index: -1, _index: -1, column, colid, index, items, parent: parentColumn || null, width: 0, oLeft: 0 };
                if (field) {
                    if (fullColFieldData[field]) {
                        errLog('vxe.error.colRepet', ['field', field]);
                    }
                    fullColFieldData[field] = rest;
                }
                else {
                    if (storage && !type) {
                        errLog('vxe.error.reqSupportProp', ['storage', `[${type ? `type=${type}` : `title=${column.getTitle()}`}]field=?`]);
                    }
                    if (columnOpts.drag && (isCrossDrag || isSelfToChildDrag)) {
                        errLog('vxe.error.reqSupportProp', ['column-drag-config.isCrossDrag | column-drag-config.isSelfToChildDrag', `${column.getTitle() || type || ''} -> field=?`]);
                    }
                }
                if (!hasFixed && fixed) {
                    hasFixed = fixed;
                }
                if (!htmlColumn && type === 'html') {
                    htmlColumn = column;
                }
                if (treeNode) {
                    if (treeNodeColumn) {
                        warnLog('vxe.error.colRepet', ['tree-node', treeNode]);
                    }
                    if (!treeNodeColumn) {
                        treeNodeColumn = column;
                    }
                }
                if (rowGroupNode) {
                    if (treeNodeColumn) {
                        warnLog('vxe.error.colRepet', ['row-group-node', rowGroupNode]);
                    }
                    if (!rowGroupColumn) {
                        rowGroupColumn = column;
                    }
                }
                if (type === 'expand') {
                    if (expandColumn) {
                        warnLog('vxe.error.colRepet', ['type', type]);
                    }
                    if (!expandColumn) {
                        expandColumn = column;
                    }
                }
                if (type === 'checkbox') {
                    if (checkboxColumn) {
                        warnLog('vxe.error.colRepet', ['type', type]);
                    }
                    if (!checkboxColumn) {
                        checkboxColumn = column;
                    }
                }
                else if (type === 'radio') {
                    if (radioColumn) {
                        warnLog('vxe.error.colRepet', ['type', type]);
                    }
                    if (!radioColumn) {
                        radioColumn = column;
                    }
                }
                if (isAllOverflow && column.showOverflow === false) {
                    isAllOverflow = false;
                }
                if (fullColIdData[colid]) {
                    errLog('vxe.error.colRepet', ['colId', colid]);
                }
                fullColIdData[colid] = rest;
            };
            if (isGroup) {
                XEUtils.eachTree(collectColumn, (column, index, items, path, parentColumn, nodes) => {
                    column.level = nodes.length;
                    handleFunc(column, index, items, path, parentColumn);
                });
            }
            else {
                tableFullColumn.forEach(handleFunc);
            }
            if (expandColumn) {
                if (expandOpts.mode !== 'fixed' && virtualYOpts.enabled) {
                    warnLog('vxe.error.notConflictProp', ['column.type="expand', 'virtual-y-config.enabled=false']);
                }
                if ((expandOpts.mode !== 'fixed') && mouseOpts.area) {
                    errLog('vxe.error.errConflicts', ['mouse-config.area', 'column.type=expand']);
                }
                if (expandOpts.mode !== 'inside' && (treeConfig && !treeOpts.transform)) {
                    errLog('vxe.error.notConflictProp', ['tree-config.transform=false', 'expand-config.mode=inside']);
                }
                // if (props.spanMethod) {
                //   warnLog('vxe.error.notSupportProp', ['column.type=expand', 'span-method', 'span-method=null'])
                // }
            }
            if (htmlColumn) {
                if (!columnOpts.useKey) {
                    errLog('vxe.error.notSupportProp', ['column.type=html', 'column-config.useKey=false', 'column-config.useKey=true']);
                }
                if (!rowOpts.useKey) {
                    errLog('vxe.error.notSupportProp', ['column.type=html', 'row-config.useKey=false', 'row-config.useKey=true']);
                }
            }
            reactData.isGroup = isGroup;
            reactData.rowGroupColumn = rowGroupColumn;
            reactData.treeNodeColumn = treeNodeColumn;
            reactData.expandColumn = expandColumn;
            reactData.checkboxColumn = checkboxColumn;
            reactData.radioColumn = radioColumn;
            reactData.isAllOverflow = isAllOverflow;
        };
        const updateHeight = () => {
            internalData.customHeight = calcTableHeight('height');
            internalData.customMinHeight = calcTableHeight('minHeight');
            internalData.customMaxHeight = calcTableHeight('maxHeight');
            // 如果启用虚拟滚动,纠正高度
            if (reactData.scrollYLoad && !(internalData.customHeight || internalData.customMinHeight || internalData.customMaxHeight)) {
                internalData.customHeight = 300;
            }
        };
        /**
         * 计算自适应列宽
         */
        const calcColumnAutoWidth = (column, wrapperEl) => {
            const { scrollYLoad } = reactData;
            const columnOpts = computeColumnOpts.value;
            const { autoOptions } = columnOpts;
            const { isCalcHeader, isCalcBody, isCalcFooter } = autoOptions || {};
            const querySelections = [];
            if (isCalcHeader) {
                querySelections.push(`.vxe-header-cell--wrapper[colid="${column.id}"]`);
            }
            if (isCalcBody) {
                querySelections.push(`.vxe-body-cell--wrapper[colid="${column.id}"]`);
            }
            if (isCalcFooter) {
                querySelections.push(`.vxe-footer-cell--wrapper[colid="${column.id}"]`);
            }
            const cellElemList = querySelections.length ? wrapperEl.querySelectorAll(querySelections.join(',')) : [];
            let leftRightPadding = 0;
            const firstCellEl = cellElemList[0];
            if (firstCellEl && firstCellEl.parentElement) {
                const cellStyle = getComputedStyle(firstCellEl.parentElement);
                leftRightPadding = Math.ceil(XEUtils.toNumber(cellStyle.paddingLeft) + XEUtils.toNumber(cellStyle.paddingRight));
            }
            let colWidth = (scrollYLoad ? column.renderAutoWidth : 0) - leftRightPadding;
            for (let i = 0; i < cellElemList.length; i++) {
                const celEl = cellElemList[i];
                colWidth = Math.max(colWidth, celEl ? Math.ceil(celEl.scrollWidth) + 4 : 0);
            }
            return colWidth + leftRightPadding;
        };
        /**
         * 自适应列宽
         */
        const calcCellWidth = () => {
            const autoWidthColumnList = computeAutoWidthColumnList.value;
            const { fullColumnIdData } = internalData;
            const el = refElem.value;
            if (el && autoWidthColumnList.length) {
                el.setAttribute('data-calc-col', 'Y');
                autoWidthColumnList.forEach(column => {
                    const colid = column.id;
                    const colRest = fullColumnIdData[colid];
                    const colWidth = calcColumnAutoWidth(column, el);
                    if (colRest) {
                        colRest.width = Math.max(colWidth, colRest.width);
                    }
                    column.renderAutoWidth = colWidth;
                });
                $xeTable.analyColumnWidth();
                el.removeAttribute('data-calc-col');
            }
        };
        /**
         * 列宽算法,计算单元格列宽,动态分配可用剩余空间
         * 支持 px、%、固定 混合分配
         * 支持动态列表调整分配
         * 支持自动分配偏移量
         * 支持 width=60 width=60px width=10% min-width=60 min-width=60px min-width=10%
         */
        const autoCellWidth = () => {
            const { elemStore } = internalData;
            const bodyWrapperElem = getRefElem(elemStore['main-body-wrapper']);
            if (!bodyWrapperElem) {
                return;
            }
            const yHandleEl = refScrollYHandleElem.value;
            if (!yHandleEl) {
                return;
            }
            const xHandleEl = refScrollXHandleElem.value;
            if (!xHandleEl) {
                return;
            }
            const columnOpts = computeColumnOpts.value;
            let tWidth = 0;
            const minCellWidth = 40; // 列宽最少限制 40px
            const bodyWidth = bodyWrapperElem.clientWidth;
            let remainWidth = bodyWidth;
            let meanWidth = remainWidth / 100;
            const { fit } = props;
            const { columnStore } = reactData;
            const { resizeList, pxMinList, autoMinList, pxList, scaleList, scaleMinList, autoList, remainList } = columnStore;
            const parseColumnMaxWidth = (column) => {
                const maxWidth = column.maxWidth || columnOpts.maxWidth;
                if (maxWidth && maxWidth !== 'auto') {
                    if (isScale(maxWidth)) {
                        return Math.floor(XEUtils.toInteger(maxWidth) * meanWidth);
                    }
                    return XEUtils.toInteger(maxWidth);
                }
                return 0;
            };
            // 最小宽
            pxMinList.forEach((column) => {
                let miWidth = XEUtils.toInteger(column.minWidth);
                const mxWidth = parseColumnMaxWidth(column);
                if (mxWidth) {
                    miWidth = Math.min(miWidth, mxWidth);
                }
                tWidth += miWidth;
                column.renderWidth = miWidth;
            });
            // 最小自适应
            autoMinList.forEach((column) => {
                let caWidth = Math.max(60, XEUtils.toInteger(column.renderAutoWidth));
                const mxWidth = parseColumnMaxWidth(column);
                if (mxWidth) {
                    caWidth = Math.min(caWidth, mxWidth);
                }
                tWidth += caWidth;
                column.renderWidth = caWidth;
            });
            // 最小百分比
            scaleMinList.forEach((column) => {
                let smWidth = Math.floor(XEUtils.toInteger(column.minWidth) * meanWidth);
                const mxWidth = parseColumnMaxWidth(column);
                if (mxWidth) {
                    smWidth = Math.min(smWidth, mxWidth);
                }
                tWidth += smWidth;
                column.renderWidth = smWidth;
            });
            // 固定百分比
            scaleList.forEach((column) => {
                let sfWidth = Math.floor(XEUtils.toInteger(column.width) * meanWidth);
                const mxWidth = parseColumnMaxWidth(column);
                if (mxWidth) {
                    sfWidth = Math.min(sfWidth, mxWidth);
                }
                tWidth += sfWidth;
                column.renderWidth = sfWidth;
            });
            // 固定宽
            pxList.forEach((column) => {
                let pWidth = XEUtils.toInteger(column.width);
                const mxWidth = parseColumnMaxWidth(column);
                if (mxWidth) {
                    pWidth = Math.min(pWidth, mxWidth);
                }
                tWidth += pWidth;
                column.renderWidth = pWidth;
            });
            // 自适应宽
            autoList.forEach((column) => {
                let aWidth = Math.max(60, XEUtils.toInteger(column.renderAutoWidth));
                const mxWidth = parseColumnMaxWidth(column);
                if (mxWidth) {
                    aWidth = Math.min(aWidth, mxWidth);
                }
                tWidth += aWidth;
                column.renderWidth = aWidth;
            });
            // 调整了列宽
            resizeList.forEach((column) => {
                const reWidth = XEUtils.toInteger(column.resizeWidth);
                tWidth += reWidth;
                column.renderWidth = reWidth;
            });
            const zoomColumnList = scaleMinList.concat(pxMinList).concat(autoMinList).filter(column => !parseColumnMaxWidth(column));
            remainWidth -= tWidth;
            meanWidth = remainWidth > 0 ? Math.floor(remainWidth / (zoomColumnList.length + remainList.length)) : 0;
            if (fit) {
                if (remainWidth > 0) {
                    zoomColumnList.forEach((column) => {
                        tWidth += meanWidth;
                        column.renderWidth += meanWidth;
                    });
                }
            }
            else {
                meanWidth = minCellWidth;
            }
            // 剩余均分
            remainList.forEach((column) => {
                const width = Math.max(meanWidth, minCellWidth);
                column.renderWidth = width;
                tWidth += width;
            });
            if (fit) {
                /**
                 * 偏移量算法
                 * 如果所有列足够放的情况下,从最后动态列开始分配
                 * 排除已设置 max-width
                 */
                const dynamicList = scaleList.concat(scaleMinList).concat(pxMinList).concat(autoMinList).concat(remainList).filter(column => !parseColumnMaxWidth(column));
                let dynamicSize = dynamicList.length - 1;
                if (dynamicSize > 0) {
                    let i = bodyWidth - tWidth;
                    if (i > 0) {
                        while (i > 0 && dynamicSize >= 0) {
                            i--;
                            dynamicList[dynamicSize--].renderWidth++;
                        }
                        tWidth = bodyWidth;
                    }
                }
            }
            reactData.scrollXWidth = tWidth;
            reactData.resizeWidthFlag++;
            updateColumnOffsetLeft();
            updateHeight();
        };
        /**
         * 计算自适应行高
         */
        const calcCellAutoHeight = (rowid, rowRest, wrapperEl) => {
            const { fullCellHeightMaps } = internalData;
            let chRest = fullCellHeightMaps[rowid];
            if (!chRest) {
                chRest = {};
                fullCellHeightMaps[rowid] = chRest;
            }
            const wrapperElemList = wrapperEl.querySelectorAll(`.vxe-cell--wrapper[rowid="${rowRest.rowid}"]`);
            let firstCellStyle = null;
            let topBottomPadding = 0;
            let changeCH = false;
            for (let i = 0; i < wrapperElemList.length; i++) {
                const wrapperElem = wrapperElemList[i];
                const cellElem = wrapperElem.parentElement;
                const cellStyle = cellElem.style;
                const orHeight = cellStyle.height;
                const colid = wrapperElem.getAttribute('colid') || '';
                cellStyle.height = '';
                if (!firstCellStyle) {
                    firstCellStyle = getComputedStyle(cellElem);
                    topBottomPadding = firstCellStyle ? Math.ceil(XEUtils.toNumber(firstCellStyle.paddingTop) + XEUtils.toNumber(firstCellStyle.paddingBottom)) : 0;
                }
                const cellHeight = wrapperElem ? wrapperElem.clientHeight : 0;
                const colHeight = Math.ceil(cellHeight + topBottomPadding);
                if (chRest[colid] !== colHeight) {
                    changeCH = true;
                    chRest[colid] = colHeight;
                }
                cellStyle.height = orHeight;
            }
            const cellMaxHeight = getRowMaxHeight(chRest, changeCH);
            return cellMaxHeight;
        };
        /**
         * 自适应行高
         */
        const calcCellHeight = () => {
            const { treeConfig } = props;
            const { tableData, isAllOverflow, scrollYLoad, scrollXLoad } = reactData;
            const { fullAllDataRowIdData } = internalData;
            const el = refElem.value;
            if (!el || !el.clientWidth) {
                return;
            }
            const treeOpts = computeTreeOpts.value;
            const defaultRowHeight = computeDefaultRowHeight.value;
            if (!isAllOverflow && (scrollYLoad || scrollXLoad || (treeConfig && treeOpts.showLine))) {
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                el.setAttribute('data-calc-row', 'Y');
                tableData.forEach(row => {
                    const rowid = handleGetRowId(row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (rowRest) {
                        const reHeight = calcCellAutoHeight(rowid, rowRest, el);
                        rowRest.height = Math.max(defaultRowHeight, reHeight);
                    }
                    el.removeAttribute('data-calc-row');
                });
                reactData.calcCellHeightFlag++;
            }
        };
        const getOrderField = (column) => {
            const { isRowGroupStatus } = reactData;
            const { sortBy, sortType, aggFunc } = column;
            return isRowGroupStatus && aggFunc
                ? (row) => {
                    if (row.isAggregate) {
                        const aggData = row.aggData;
                        const currAggData = aggData ? aggData[column.field] : null;
                        return currAggData ? currAggData.value : null;
                    }
                    let cellValue;
                    if (sortBy) {
                        cellValue = XEUtils.isFunction(sortBy) ? sortBy({ row, column }) : XEUtils.get(row, sortBy);
                    }
                    else {
                        cellValue = $xeTable.getCellLabel(row, column);
                    }
                    if (!sortType || sortType === 'auto') {
                        return eqEmptyValue(cellValue) || isNaN(cellValue) ? cellValue : XEUtils.toNumber(cellValue);
                    }
                    else if (sortType === 'number') {
                        return XEUtils.toNumber(cellValue);
                    }
                    else if (sortType === 'string') {
                        return XEUtils.toValueString(cellValue);
                    }
                    return cellValue;
                }
                : (row) => {
                    let cellValue;
                    if (sortBy) {
                        cellValue = XEUtils.isFunction(sortBy) ? sortBy({ row, column }) : XEUtils.get(row, sortBy);
                    }
                    else {
                        cellValue = $xeTable.getCellLabel(row, column);
                    }
                    if (!sortType || sortType === 'auto') {
                        return eqEmptyValue(cellValue) || isNaN(cellValue) ? cellValue : XEUtils.toNumber(cellValue);
                    }
                    else if (sortType === 'number') {
                        return XEUtils.toNumber(cellValue);
                    }
                    else if (sortType === 'string') {
                        return XEUtils.toValueString(cellValue);
                    }
                    return cellValue;
                };
        };
        const updateAfterTreeIndex = () => {
            const { fullDataRowIdData, fullAllDataRowIdData, afterFullData, afterTreeFullData } = internalData;
            const treeOpts = computeTreeOpts.value;
            const { transform, mapChildrenField } = treeOpts;
            const childrenField = treeOpts.children || treeOpts.childrenField;
            const fullMaps = {};
            let rowNum = 0;
            const { handleGetRowId } = createHandleGetRowId($xeTable);
            XEUtils.eachTree(afterTreeFullData, (row, index, items, path, parentRow) => {
                const rowid = handleGetRowId(row);
                const rowRest = fullAllDataRowIdData[rowid];
                const seq = path.map((num, i) => i % 2 === 0 ? (Number(num) + 1) : '.').join('');
                if (rowRest) {
                    rowRest.seq = seq;
                    rowRest._seq = rowNum;
                    rowRest.treeIndex = index;
                    rowRest._index = rowNum;
                    rowRest._tIndex = rowNum;
                }
                else {
                    const rest = { row, rowid, _seq: rowNum, seq, index, $index: -1, _index: rowNum, treeIndex: index, _tIndex: rowNum, items, parent: parentRow, level: 0, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 };
                    fullAllDataRowIdData[rowid] = rest;
                    fullDataRowIdData[rowid] = rest;
                }
                rowNum++;
                fullMaps[rowid] = row;
            }, { children: transform ? mapChildrenField : childrenField });
            if (transform) {
                afterFullData.forEach((row, index) => {
                    const rowid = handleGetRowId(row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (rowRest) {
                        rowRest._index = index;
                    }
                });
            }
            internalData.afterFullRowMaps = fullMaps;
        };
        const updateAfterListIndex = () => {
            const { afterFullData, fullDataRowIdData, fullAllDataRowIdData } = internalData;
            const { handleGetRowId } = createHandleGetRowId($xeTable);
            const fullMaps = {};
            let rowNum = 0;
            afterFullData.forEach((row, index) => {
                const rowid = handleGetRowId(row);
                const rowRest = fullAllDataRowIdData[rowid];
                const seq = index + 1;
                if (rowRest) {
                    rowRest.seq = seq;
                    rowRest._seq = rowNum;
                    rowRest._index = index;
                }
                else {
                    const rest = { row, rowid, _seq: rowNum, seq, index: -1, $index: -1, _index: index, treeIndex: -1, _tIndex: -1, items: [], parent: null, level: 0, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 };
                    fullAllDataRowIdData[rowid] = rest;
                    fullDataRowIdData[rowid] = rest;
                }
                rowNum++;
                fullMaps[rowid] = row;
            });
            internalData.afterFullRowMaps = fullMaps;
        };
        /**
         * 预编译
         * 对渲染中的数据提前解析序号及索引。牺牲提前编译耗时换取渲染中额外损耗,使运行时更加流畅
         */
        const updateAfterDataIndex = () => {
            const { treeConfig } = props;
            if (treeConfig) {
                updateAfterTreeIndex();
            }
            else {
                updateAfterListIndex();
            }
        };
        /**
         * 如果为虚拟树、行分组、则将树结构拍平
         * @returns
         */
        const handleVirtualTreeToList = () => {
            const { treeConfig } = props;
            const { isRowGroupStatus } = reactData;
            const { fullAllDataRowIdData, treeExpandedMaps, rowGroupExpandedMaps } = internalData;
            const aggregateOpts = computeAggregateOpts.value;
            const treeOpts = computeTreeOpts.value;
            const { handleGetRowId } = createHandleGetRowId($xeTable);
            const fullData = [];
            const expandMaps = {};
            if (treeConfig && treeOpts.transform) {
                const childrenField = treeOpts.children || treeOpts.childrenField;
                XEUtils.eachTree(internalData.afterTreeFullData, (row, index, items, path, parentRow) => {
                    const rowid = handleGetRowId(row);
                    const parentRowid = handleGetRowId(parentRow);
                    if (!parentRow || (expandMaps[parentRowid] && treeExpandedMaps[parentRowid])) {
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            rowRest._index = fullData.length;
                        }
                        expandMaps[rowid] = 1;
                        fullData.push(row);
                    }
                }, { children: childrenField });
                internalData.afterFullData = fullData;
                updateScrollYStatus(fullData);
                return fullData;
            }
            else if (isRowGroupStatus) {
                const { childrenField } = aggregateOpts;
                XEUtils.eachTree(internalData.afterGroupFullData, (row, index, items, path, parentRow) => {
                    const rowid = handleGetRowId(row);
                    const parentRowid = handleGetRowId(parentRow);
                    if (!parentRow || (expandMaps[parentRowid] && rowGroupExpandedMaps[parentRowid])) {
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            rowRest._index = fullData.length;
                        }
                        expandMaps[rowid] = 1;
                        fullData.push(row);
                    }
                }, { children: childrenField });
                internalData.afterFullData = fullData;
                updateScrollYStatus(fullData);
                return fullData;
            }
            return internalData.afterFullData;
        };
        /**
         * 编译处理后全量的表格数据
         * 如果存在筛选条件,继续处理
         */
        const updateAfterFullData = () => {
            const { treeConfig } = props;
            const { isRowGroupStatus } = reactData;
            const { tableFullColumn, tableFullData, tableFullTreeData, tableFullGroupData } = internalData;
            const filterOpts = computeFilterOpts.value;
            const sortOpts = computeSortOpts.value;
            const aggregateOpts = computeAggregateOpts.value;
            const treeOpts = computeTreeOpts.value;
            const childrenField = treeOpts.children || treeOpts.childrenField;
            const { transform, rowField, parentField, mapChildrenField } = treeOpts;
            const { isEvery, remote: allRemoteFilter, filterMethod: allFilterMethod, isDeep: isFilterDeep } = filterOpts;
            const { remote: allRemoteSort, sortMethod: allSortMethod, multiple: sortMultiple, chronological, isDeep: isSortDeep } = sortOpts;
            let tableData = [];
            let tableTree = [];
            // 处理数据
            if (!allRemoteFilter || !allRemoteSort) {
                const filterColumns = [];
                let orderColumns = [];
                tableFullColumn.forEach((column) => {
                    const { field, sortable, order, filters } = column;
                    if (!allRemoteFilter && filters && filters.length) {
                        const valueList = [];
                        const itemList = [];
                        filters.forEach((item) => {
                            if (item.checked) {
                                itemList.push(item);
                                valueList.push(item.value);
                            }
                        });
                        if (itemList.length) {
                            filterColumns.push({ column, valueList, itemList });
                        }
                    }
                    if (!allRemoteSort && sortable && order) {
                        orderColumns.push({ column, field, property: field, order: order, sortTime: column.sortTime });
                    }
                });
                if (sortMultiple && chronological && orderColumns.length > 1) {
                    orderColumns = XEUtils.orderBy(orderColumns, 'sortTime');
                }
                // 处理筛选
                // 支持单列、多列、组合筛选
                if (!allRemoteFilter && filterColumns.length) {
                    const handleFilter = (row) => {
                        return filterColumns.every(({ column, valueList, itemList }) => {
                            const { filterMethod, filterRender } = column;
                            const compConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null;
                            const compFilterMethod = compConf ? (compConf.tableFilterMethod || compConf.filterMethod) : null;
                            const tdFilterMethod = compConf ? (compConf.tableFilterDefaultMethod || compConf.defaultTableFilterMethod || compConf.defaultFilterMethod) : null;
                            const cellValue = getCellValue(row, column);
                            if (filterMethod) {
                                return itemList.some((item) => filterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
                            }
                            else if (compFilterMethod) {
                                return itemList.some((item) => compFilterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
                            }
                            else if (allFilterMethod) {
                                return allFilterMethod({ $table: $xeTable, options: itemList, values: valueList, cellValue, row, column });
                            }
                            else if (tdFilterMethod) {
                                return itemList.some((item) => tdFilterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
                            }
                            return valueList.indexOf(XEUtils.get(row, column.field)) > -1;
                        });
                    };
                    if (isRowGroupStatus) {
                        // 行分组
                        tableTree = XEUtils.searchTree(tableFullGroupData, handleFilter, {
                            original: true,
                            isEvery: true,
                            children: aggregateOpts.mapChildrenField,
                            mapChildren: aggregateOpts.childrenField
                        });
                        tableData = tableTree;
                    }
                    else if (treeConfig && transform && isFilterDeep !== false) {
                        // 筛选虚拟树
                        tableTree = XEUtils.searchTree(tableFullTreeData, handleFilter, {
                            original: true,
                            isEvery,
                            children: mapChildrenField,
                            mapChildren: childrenField
                        });
                        tableData = tableTree;
                    }
                    else {
                        tableData = treeConfig ? tableFullTreeData.filter(handleFilter) : tableFullData.filter(handleFilter);
                        tableTree = tableData;
                    }
                }
                else {
                    if (isRowGroupStatus) {
                        // 还原行分组
                        tableTree = XEUtils.searchTree(tableFullGroupData, () => true, {
                            original: true,
                            isEvery: true,
                            children: aggregateOpts.mapChildrenField,
                            mapChildren: aggregateOpts.childrenField
                        });
                        tableData = tableTree;
                    }
                    else if (treeConfig && transform && isFilterDeep !== false) {
                        // 还原虚拟树
                        tableTree = XEUtils.searchTree(tableFullTreeData, () => true, {
                            original: true,
                            isEvery,
                            children: mapChildrenField,
                            mapChildren: childrenField
                        });
                        tableData = tableTree;
                    }
                    else {
                        tableData = treeConfig ? tableFullTreeData.slice(0) : tableFullData.slice(0);
                        tableTree = tableData;
                    }
                }
                // 处理排序
                // 支持单列、多列、组合排序
                if (!allRemoteSort && orderColumns.length) {
                    if (isRowGroupStatus) {
                        // 行分组的排序
                        if (allSortMethod) {
                            const sortRests = allSortMethod({ data: tableTree, sortList: orderColumns, $table: $xeTable });
                            tableTree = XEUtils.isArray(sortRests) ? sortRests : tableTree;
                        }
                        else {
                            const treeList = XEUtils.toTreeArray(tableTree, {
                                key: aggregateOpts.rowField,
                                parentKey: aggregateOpts.parentField,
                                children: aggregateOpts.mapChildrenField
                            });
                            tableTree = XEUtils.toArrayTree(XEUtils.orderBy(treeList, orderColumns.map(({ column, order }) => [getOrderField(column), order])), {
                                key: aggregateOpts.rowField,
                                parentKey: aggregateOpts.parentField,
                                children: aggregateOpts.childrenField,
                                mapChildren: aggregateOpts.mapChildrenField
                            });
                        }
                        tableData = tableTree;
                    }
                    else if (treeConfig && transform && isSortDeep !== false) {
                        // 虚拟树的排序
                        if (allSortMethod) {
                            const sortRests = allSortMethod({ data: tableTree, sortList: orderColumns, $table: $xeTable });
                            tableTree = XEUtils.isArray(sortRests) ? sortRests : tableTree;
                        }
                        else {
                            const treeList = XEUtils.toTreeArray(tableTree, {
                                children: mapChildrenField
                            });
                            tableTree = XEUtils.toArrayTree(XEUtils.orderBy(treeList, orderColumns.map(({ column, order }) => [getOrderField(column), order])), {
                                key: rowField,
                                parentKey: parentField,
                                children: childrenField,
                                mapChildren: mapChildrenField
                            });
                        }
                        tableData = tableTree;
                    }
                    else {
                        if (allSortMethod) {
                            const sortRests = allSortMethod({ data: tableData, sortList: orderColumns, $table: $xeTable });
                            tableData = XEUtils.isArray(sortRests) ? sortRests : tableData;
                        }
                        else {
                            tableData = XEUtils.orderBy(tableData, orderColumns.map(({ column, order }) => [getOrderField(column), order]));
                        }
                        tableTree = tableData;
                    }
                }
            }
            else {
                if (isRowGroupStatus) {
                    // 还原行分组
                    // 还原虚拟树
                    tableTree = XEUtils.searchTree(tableFullGroupData, () => true, {
                        original: true,
                        isEvery: true,
                        children: aggregateOpts.mapChildrenField,
                        mapChildren: aggregateOpts.childrenField
                    });
                    tableData = tableTree;
                }
                else if (treeConfig && transform && isSortDeep !== false) {
                    // 还原虚拟树
                    tableTree = XEUtils.searchTree(tableFullTreeData, () => true, {
                        original: true,
                        isEvery,
                        children: mapChildrenField,
                        mapChildren: childrenField
                    });
                    tableData = tableTree;
                }
                else {
                    tableData = treeConfig ? tableFullTreeData.slice(0) : tableFullData.slice(0);
                    tableTree = tableData;
                }
            }
            internalData.afterFullData = tableData;
            internalData.afterTreeFullData = tableTree;
            internalData.afterGroupFullData = tableTree;
            updateAfterDataIndex();
        };
        const updateStyle = () => {
            const { mouseConfig } = props;
            const { isGroup, tableColumn, overflowX, scrollbarWidth, overflowY, scrollbarHeight, scrollXWidth, columnStore, editStore, isColLoading } = reactData;
            const { visibleColumn, tableHeight, elemStore, currentRow, customHeight, customMinHeight, customMaxHeight, tHeaderHeight, tFooterHeight } = internalData;
            const $xeGanttView = internalData.xeGanttView;
            const el = refElem.value;
            if (!el || (internalData.tBodyHeight && !el.clientHeight)) {
                return;
            }
            const containerList = ['main', 'left', 'right'];
            const { leftList, rightList } = columnStore;
            let osbWidth = overflowY ? scrollbarWidth : 0;
            let osbHeight = overflowX ? scrollbarHeight : 0;
            const emptyPlaceholderElem = refEmptyPlaceholder.value;
            const isHeaderRenderOptimize = computeIsHeaderRenderOptimize.value;
            const isBodyRenderOptimize = computeIsBodyRenderOptimize.value;
            const isFooterRenderOptimize = computeIsFooterRenderOptimize.value;
            const scrollbarOpts = computeScrollbarOpts.value;
            const mouseOpts = computeMouseOpts.value;
            const bodyWrapperElem = getRefElem(elemStore['main-body-wrapper']);
            const bodyTableElem = getRefElem(elemStore['main-body-table']);
            if (emptyPlaceholderElem) {
                emptyPlaceholderElem.style.top = `${tHeaderHeight}px`;
                emptyPlaceholderElem.style.height = bodyWrapperElem ? `${bodyWrapperElem.offsetHeight - osbHeight}px` : '';
            }
            const scrollbarXConf = scrollbarOpts.x || {};
            const scrollbarYConf = scrollbarOpts.y || {};
            const scrollbarYToLeft = computeScrollbarYToLeft.value;
            let xScrollbarVisible = overflowX ? 'visible' : 'hidden';
            if (scrollbarXConf.visible === 'visible' || $xeGanttView) {
                osbHeight = scrollbarHeight;
                xScrollbarVisible = 'visible';
            }
            else if (scrollbarXConf.visible === 'hidden' || scrollbarXConf.visible === false) {
                osbHeight = 0;
                xScrollbarVisible = 'hidden';
            }
            let yScrollbarVisible = overflowY ? 'visible' : 'hidden';
            if ((scrollbarYConf.visible === 'hidden' || scrollbarYConf.visible === false) || (($xeGantt && $xeGanttView && $xeGantt.reactData.showRightView) && !scrollbarYToLeft)) {
                osbWidth = 0;
                yScrollbarVisible = 'hidden';
            }
            else if (scrollbarYConf.visible === 'visible') {
                osbWidth = scrollbarWidth;
                yScrollbarVisible = 'visible';
            }
            let tbHeight = 0;
            let bodyMaxHeight = 0;
            const bodyMinHeight = customMinHeight - tHeaderHeight - tFooterHeight - osbHeight;
            if (customMaxHeight) {
                bodyMaxHeight = Math.max(bodyMinHeight, customMaxHeight - tHeaderHeight - tFooterHeight - osbHeight);
            }
            if (customHeight) {
                tbHeight = customHeight - tHeaderHeight - tFooterHeight - osbHeight;
            }
            if (!tbHeight) {
                if (bodyTableElem) {
                    tbHeight = bodyTableElem.clientHeight;
                }
            }
            if (tbHeight) {
                if (bodyMaxHeight) {
                    tbHeight = Math.min(bodyMaxHeight, tbHeight);
                }
                tbHeight = Math.max(bodyMinHeight, tbHeight);
            }
            const xLeftCornerEl = refScrollXLeftCornerElem.value;
            const xRightCornerEl = refScrollXRightCornerElem.value;
            const scrollXVirtualEl = refScrollXVirtualElem.value;
            if (scrollXVirtualEl) {
                scrollXVirtualEl.style.height = `${osbHeight}px`;
                scrollXVirtualEl.style.visibility = xScrollbarVisible;
            }
            const xWrapperEl = refScrollXWrapperElem.value;
            if (xWrapperEl) {
                xWrapperEl.style.width = `${el.clientWidth - osbWidth}px`;
                if (scrollbarYToLeft) {
                    xWrapperEl.style.left = `${osbWidth}px`;
                }
                else {
                    xWrapperEl.style.left = '';
                }
            }
            if (xLeftCornerEl) {
                if (scrollbarYToLeft) {
                    xLeftCornerEl.style.width = `${osbWidth}px`;
                    xLeftCornerEl.style.display = overflowY && osbWidth ? 'block' : '';
                }
                else {
                    xLeftCornerEl.style.display = '';
                }
            }
            if (xRightCornerEl) {
                if (scrollbarYToLeft) {
                    xRightCornerEl.style.display = '';
                }
                else {
                    xRightCornerEl.style.width = `${osbWidth}px`;
                    xRightCornerEl.style.display = xScrollbarVisible === 'visible' ? 'block' : '';
                }
            }
            const scrollYVirtualEl = refScrollYVirtualElem.value;
            if (scrollYVirtualEl) {
                scrollYVirtualEl.style.width = `${osbWidth}px`;
                scrollYVirtualEl.style.height = `${tbHeight + tHeaderHeight + tFooterHeight}px`;
                scrollYVirtualEl.style.visibility = yScrollbarVisible;
            }
            const yTopCornerEl = refScrollYTopCornerElem.value;
            if (yTopCornerEl) {
                yTopCornerEl.style.height = `${tHeaderHeight}px`;
                yTopCornerEl.style.display = tHeaderHeight && yScrollbarVisible === 'visible' ? 'block' : '';
            }
            const yWrapperEl = refScrollYWrapperElem.value;
            if (yWrapperEl) {
                yWrapperEl.style.height = `${tbHeight}px`;
                yWrapperEl.style.top = `${tHeaderHeight}px`;
            }
            const yBottomCornerEl = refScrollYBottomCornerElem.value;
            if (yBottomCornerEl) {
                yBottomCornerEl.style.height = `${tFooterHeight}px`;
                yBottomCornerEl.style.top = `${tHeaderHeight + tbHeight}px`;
                yBottomCornerEl.style.display = tFooterHeight && yScrollbarVisible === 'visible' ? 'block' : '';
            }
            const rowExpandEl = refRowExpandElem.value;
            if (rowExpandEl) {
                rowExpandEl.style.height = `${tbHeight}px`;
                rowExpandEl.style.top = `${tHeaderHeight}px`;
            }
            internalData.tBodyHeight = tbHeight;
            containerList.forEach((name, index) => {
                const fixedType = index > 0 ? name : '';
                const layoutList = ['header', 'body', 'footer'];
                const isFixedLeft = fixedType === 'left';
                let fixedColumn = [];
                let fixedWrapperElem;
                if (fixedType) {
                    fixedColumn = isFixedLeft ? leftList : rightList;
                    fixedWrapperElem = isFixedLeft ? refLeftContainer.value : refRightContainer.value;
                }
                layoutList.forEach(layout => {
                    const wrapperElem = getRefElem(elemStore[`${name}-${layout}-wrapper`]);
                    const currScrollElem = getRefElem(elemStore[`${name}-${layout}-scroll`]);
                    const tableElem = getRefElem(elemStore[`${name}-${layout}-table`]);
                    if (layout === 'header') {
                        // 表头体样式处理
                        // 横向滚动渲染
                        let renderColumnList = tableColumn;
                        const isOptimizeMode = isHeaderRenderOptimize;
                        if (isGroup) {
                            renderColumnList = visibleColumn;
                        }
                        else {
                            if (!isOptimizeMode || (!isColLoading && (fixedType || !overflowX))) {
                                renderColumnList = visibleColumn;
                            }
                            if (fixedType) {
                                // 如果是使用优化模式
                                if (isOptimizeMode) {
                                    renderColumnList = fixedColumn || [];
                                }
                            }
                        }
                        const tWidth = renderColumnList.reduce((previous, column) => previous + column.renderWidth, 0);
                        if (fixedType) {
                            if (isGroup) {
                                if (wrapperElem) {
                                    wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : '';
                                }
                            }
                            else {
                                if (isOptimizeMode) {
                                    if (wrapperElem) {
                                        wrapperElem.style.width = tWidth ? `${tWidth}px` : '';
                                    }
                                }
                                else {
                                    if (wrapperElem) {
                                        wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : '';
                                    }
                                }
                            }
                        }
                        if (currScrollElem) {
                            currScrollElem.style.height = `${tHeaderHeight}px`;
                        }
                        if (tableElem) {
                            tableElem.style.width = tWidth ? `${tWidth}px` : '';
                        }
                    }
                    else if (layout === 'body') {
                        if (currScrollElem) {
                            currScrollElem.style.maxHeight = customMaxHeight ? `${bodyMaxHeight}px` : '';
                            currScrollElem.style.height = customHeight ? `${tbHeight}px` : '';
                            currScrollElem.style.minHeight = `${bodyMinHeight}px`;
                        }
                        // 如果是固定列
                        if (fixedWrapperElem) {
                            if (wrapperElem) {
                                wrapperElem.style.top = `${tHeaderHeight}px`;
                            }
                            fixedWrapperElem.style.height = `${customHeight > 0 ? customHeight : (tableHeight + tHeaderHeight + tFooterHeight + osbHeight)}px`;
                            fixedWrapperElem.style.width = `${fixedColumn.reduce((previous, column) => previous + column.renderWidth, 0)}px`;
                        }
                        let renderColumnList = tableColumn;
                        const isOptimizeMode = isBodyRenderOptimize;
                        if (fixedType) {
                            renderColumnList = visibleColumn;
                            if (isOptimizeMode) {
                                renderColumnList = fixedColumn || [];
                            }
                        }
                        const tWidth = renderColumnList.reduce((previous, column) => previous + column.renderWidth, 0);
                        if (fixedType) {
                            if (isOptimizeMode) {
                                if (wrapperElem) {
                                    wrapperElem.style.width = tWidth ? `${tWidth}px` : '';
                                }
                            }
                            else {
                                if (wrapperElem) {
                                    wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : '';
                                }
                            }
                        }
                        if (tableElem) {
                            tableElem.style.width = tWidth ? `${tWidth}px` : '';
                            // 兼容性处理
                            tableElem.style.paddingRight = osbWidth && fixedType && (browseObj.firefox || browseObj.safari) ? `${osbWidth}px` : '';
                        }
                        const emptyBlockElem = getRefElem(elemStore[`${name}-${layout}-emptyBlock`]);
                        if (emptyBlockElem) {
                            emptyBlockElem.style.width = tWidth ? `${tWidth}px` : '';
                        }
                    }
                    else if (layout === 'footer') {
                        let renderColumnList = tableColumn;
                        const isOptimizeMode = isFooterRenderOptimize;
                        if (!isOptimizeMode || (!isColLoading && (fixedType || !overflowX))) {
                            renderColumnList = visibleColumn;
                        }
                        if (fixedType) {
                            if (isOptimizeMode) {
                                renderColumnList = fixedColumn || [];
                            }
                        }
                        const tWidth = renderColumnList.reduce((previous, column) => previous + column.renderWidth, 0);
                        if (fixedType) {
                            if (isOptimizeMode) {
                                if (wrapperElem) {
                                    wrapperElem.style.width = tWidth ? `${tWidth}px` : '';
                                }
                            }
                            else {
                                if (wrapperElem) {
                                    wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : '';
                                }
                            }
                        }
                        if (currScrollElem) {
                            currScrollElem.style.height = `${tFooterHeight}px`;
                            // 如果是固定列
                            if (fixedWrapperElem) {
                                if (wrapperElem) {
                                    wrapperElem.style.top = `${customHeight > 0 ? customHeight - tFooterHeight - osbHeight : tableHeight + tHeaderHeight}px`;
                                }
                            }
                        }
                        if (tableElem) {
                            tableElem.style.width = tWidth ? `${tWidth}px` : '';
                        }
                    }
                });
            });
            if (currentRow) {
                $xeTable.setCurrentRow(currentRow);
            }
            if (mouseConfig && mouseOpts.selected && editStore.selected.row && editStore.selected.column) {
                $xeTable.addCellSelectedClass();
            }
            if ($xeGanttView && $xeGanttView.handleUpdateStyle) {
                $xeGanttView.handleUpdateStyle();
            }
            return nextTick();
        };
        const checkValidate = (type) => {
            if ($xeTable.triggerValidate) {
                return $xeTable.triggerValidate(type);
            }
            return nextTick();
        };
        /**
         * 当单元格发生改变时
         * 如果存在规则,则校验
         */
        const handleChangeCell = (evnt, params) => {
            checkValidate('blur')
                .catch((e) => e)
                .then(() => {
                $xeTable.handleEdit(params, evnt)
                    .then(() => checkValidate('change'))
                    .catch((e) => e);
            });
        };
        const handleDefaultSort = () => {
            const { sortConfig } = props;
            if (sortConfig) {
                const sortOpts = computeSortOpts.value;
                let { defaultSort } = sortOpts;
                if (defaultSort) {
                    if (!XEUtils.isArray(defaultSort)) {
                        defaultSort = [defaultSort];
                    }
                    if (defaultSort.length) {
                        (sortConfig.multiple ? defaultSort : defaultSort.slice(0, 1)).forEach((item, index) => {
                            const { field, order } = item;
                            if (field && order) {
                                const column = $xeTable.getColumnByField(field);
                                if (column && column.sortable) {
                                    column.order = order;
                                    column.sortTime = Date.now() + index;
                                }
                            }
                        });
                        if (!sortOpts.remote) {
                            $xeTable.handleTableData(true).then(updateStyle);
                        }
                    }
                }
            }
        };
        /**
         * 处理默认勾选
         */
        const handleDefaultSelectionChecked = () => {
            const { checkboxConfig } = props;
            if (checkboxConfig) {
                const { fullDataRowIdData } = internalData;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkAll, checkRowKeys } = checkboxOpts;
                if (checkAll) {
                    handleCheckedAllCheckboxRow(true, true);
                }
                else if (checkRowKeys) {
                    const defSelection = [];
                    checkRowKeys.forEach((rowKey) => {
                        const rowid = encodeRowid(rowKey);
                        if (fullDataRowIdData[rowid]) {
                            defSelection.push(fullDataRowIdData[rowid].row);
                        }
                    });
                    handleCheckedCheckboxRow(defSelection, true, true);
                }
            }
        };
        /**
         * 处理单选框默认勾选
         */
        const handleDefaultRadioChecked = () => {
            const { radioConfig } = props;
            if (radioConfig) {
                const { fullDataRowIdData } = internalData;
                const radioOpts = computeRadioOpts.value;
                const { checkRowKey: rowKey, reserve } = radioOpts;
                const rowid = rowKey ? encodeRowid(rowKey) : null;
                if (rowid) {
                    if (fullDataRowIdData[rowid]) {
                        handleCheckedRadioRow(fullDataRowIdData[rowid].row, true);
                    }
                    if (reserve) {
                        const rowkey = getRowkey($xeTable);
                        internalData.radioReserveRow = { [rowkey]: rowid };
                    }
                }
            }
        };
        /**
         * 处理默认展开行
         */
        const handleDefaultRowExpand = () => {
            const { expandConfig } = props;
            if (expandConfig) {
                const { fullDataRowIdData } = internalData;
                const expandOpts = computeExpandOpts.value;
                const { expandAll, expandRowKeys } = expandOpts;
                if (expandAll) {
                    $xeTable.setAllRowExpand(true);
                }
                else if (expandRowKeys) {
                    const defExpandeds = [];
                    expandRowKeys.forEach((rowKey) => {
                        const rowid = encodeRowid(rowKey);
                        if (fullDataRowIdData[rowid]) {
                            defExpandeds.push(fullDataRowIdData[rowid].row);
                        }
                    });
                    $xeTable.setRowExpand(defExpandeds, true);
                }
            }
        };
        const handleRadioReserveRow = (row) => {
            const radioOpts = computeRadioOpts.value;
            if (radioOpts.reserve) {
                internalData.radioReserveRow = row;
            }
        };
        const handleCheckboxReserveRow = (row, checked) => {
            const { checkboxReserveRowMap } = internalData;
            const checkboxOpts = computeCheckboxOpts.value;
            if (checkboxOpts.reserve) {
                const rowid = getRowid($xeTable, row);
                if (checked) {
                    checkboxReserveRowMap[rowid] = row;
                }
                else if (checkboxReserveRowMap[rowid]) {
                    delete checkboxReserveRowMap[rowid];
                }
            }
        };
        const handleCheckedRadioRow = (row, isForce) => {
            const radioOpts = computeRadioOpts.value;
            const { checkMethod } = radioOpts;
            if (row && (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row })))) {
                reactData.selectRadioRow = row;
                handleRadioReserveRow(row);
            }
            return nextTick();
        };
        const handleCheckedCheckboxRow = (rows, value, isForce) => {
            if (rows && !XEUtils.isArray(rows)) {
                rows = [rows];
            }
            $xeTable.handleBatchSelectRows(rows, !!value, isForce);
            $xeTable.checkSelectionStatus();
            return nextTick();
        };
        const handleCheckedAllCheckboxRow = (checked, isForce) => {
            const { treeConfig } = props;
            const { isRowGroupStatus } = reactData;
            const { afterFullData, afterTreeFullData, afterGroupFullData, checkboxReserveRowMap, selectCheckboxMaps } = internalData;
            const treeOpts = computeTreeOpts.value;
            const aggregateOpts = computeAggregateOpts.value;
            const childrenField = treeOpts.children || treeOpts.childrenField;
            const checkboxOpts = computeCheckboxOpts.value;
            const { checkField, reserve, checkMethod } = checkboxOpts;
            const { handleGetRowId } = createHandleGetRowId($xeTable);
            // indeterminateField 仅支持读取
            const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField;
            const selectRowMaps = {};
            /**
             * 绑定属性方式(有污染)
             * 必须在行数据存在对应的属性,否则将不响应
             */
            if (checkField) {
                const checkValFn = (row) => {
                    if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
                        if (checked) {
                            selectRowMaps[handleGetRowId(row)] = row;
                        }
                        XEUtils.set(row, checkField, checked);
                    }
                    if ((treeConfig || isRowGroupStatus) && indeterminateField) {
                        XEUtils.set(row, indeterminateField, false);
                    }
                };
                // 如果存在选中方法
                // 如果方法成立,则更新值,否则忽略该数据
                if ((treeConfig || isRowGroupStatus)) {
                    XEUtils.eachTree(afterFullData, checkValFn, { children: childrenField });
                }
                else {
                    afterFullData.forEach(checkValFn);
                }
            }
            else {
                /**
                 * 默认方式(无污染)
                 * 无需任何属性,直接绑定
                 */
                if (isRowGroupStatus) {
                    if (checked) {
                        /**
                         * 如果是行分组勾选
                         * 如果方法成立,则添加到临时集合中
                         */
                        XEUtils.eachTree(afterGroupFullData, (row) => {
                            if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
                                const rowid = handleGetRowId(row);
                                selectRowMaps[rowid] = row;
                            }
                        }, { children: aggregateOpts.mapChildrenField });
                    }
                    else {
                        /**
                         * 如果是树取消
                         * 如果方法成立,则不添加到临时集合中
                         */
                        if (!isForce && checkMethod) {
                            XEUtils.eachTree(afterGroupFullData, (row) => {
                                const rowid = handleGetRowId(row);
                                if (checkMethod({ $table: $xeTable, row }) ? false : selectCheckboxMaps[rowid]) {
                                    selectRowMaps[rowid] = row;
                                }
                            }, { children: aggregateOpts.mapChildrenField });
                        }
                    }
                }
                else if (treeConfig) {
                    if (checked) {
                        /**
                         * 如果是树勾选
                         * 如果方法成立,则添加到临时集合中
                         */
                        XEUtils.eachTree(afterTreeFullData, (row) => {
                            if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
                                const rowid = handleGetRowId(row);
                                selectRowMaps[rowid] = row;
                            }
                        }, { children: childrenField });
                    }
                    else {
                        /**
                         * 如果是树取消
                         * 如果方法成立,则不添加到临时集合中
                         */
                        if (!isForce && checkMethod) {
                            XEUtils.eachTree(afterTreeFullData, (row) => {
                                const rowid = handleGetRowId(row);
                                if (checkMethod({ $table: $xeTable, row }) ? false : selectCheckboxMaps[rowid]) {
                                    selectRowMaps[rowid] = row;
                                }
                            }, { children: childrenField });
                        }
                    }
                }
                else {
                    if (checked) {
                        /**
                         * 如果是行勾选
                         * 如果存在选中方法且成立或者本身已勾选,则添加到临时集合中
                         * 如果不存在选中方法,则添加所有数据到临时集合中
                         */
                        if (!isForce && checkMethod) {
                            afterFullData.forEach((row) => {
                                const rowid = handleGetRowId(row);
                                if (selectCheckboxMaps[rowid] || checkMethod({ $table: $xeTable, row })) {
                                    selectRowMaps[rowid] = row;
                                }
                            });
                        }
                        else {
                            afterFullData.forEach(row => {
                                const rowid = handleGetRowId(row);
                                selectRowMaps[rowid] = row;
                            });
                        }
                    }
                    else {
                        /**
                         * 如果是行取消
                         * 如果方法成立,则不添加到临时集合中;如果方法不成立则判断当前是否已勾选,如果已被勾选则添加到新集合中
                         * 如果不存在选中方法,无需处理,临时集合默认为空
                         */
                        if (!isForce && checkMethod) {
                            afterFullData.forEach((row) => {
                                const rowid = handleGetRowId(row);
                                if (checkMethod({ $table: $xeTable, row }) ? false : selectCheckboxMaps[rowid]) {
                                    selectRowMaps[rowid] = row;
                                }
                            });
                        }
                    }
                }
            }
            if (reserve) {
                if (checked) {
                    XEUtils.each(selectRowMaps, (row, rowid) => {
                        checkboxReserveRowMap[rowid] = row;
                    });
                }
                else {
                    afterFullData.forEach((row) => handleCheckboxReserveRow(row, false));
                }
            }
            reactData.updateCheckboxFlag++;
            internalData.selectCheckboxMaps = checkField ? {} : selectRowMaps;
            reactData.isAllSelected = checked;
            reactData.isIndeterminate = false;
            internalData.treeIndeterminateRowMaps = {};
            $xeTable.checkSelectionStatus();
            return nextTick();
        };
        // 还原展开、选中等相关状态
        const handleReserveStatus = () => {
            const { treeConfig } = props;
            const { expandColumn, selectRadioRow } = reactData;
            const { fullDataRowIdData, fullAllDataRowIdData, radioReserveRow, selectCheckboxMaps, treeExpandedMaps, rowExpandedMaps, currentRow } = internalData;
            const expandOpts = computeExpandOpts.value;
            const treeOpts = computeTreeOpts.value;
            const radioOpts = computeRadioOpts.value;
            const checkboxOpts = computeCheckboxOpts.value;
            // 单选框
            if (selectRadioRow && !fullAllDataRowIdData[getRowid($xeTable, selectRadioRow)]) {
                reactData.selectRadioRow = null; // 刷新单选行状态
            }
            // 还原保留选中状态
            if (radioOpts.reserve && radioReserveRow) {
                const rowid = getRowid($xeTable, radioReserveRow);
                if (fullDataRowIdData[rowid]) {
                    handleCheckedRadioRow(fullDataRowIdData[rowid].row, true);
                }
            }
            // 复选框
            internalData.selectCheckboxMaps = getRecoverRowMaps(selectCheckboxMaps); // 刷新多选行状态
            reactData.updateCheckboxFlag++;
            // 还原保留选中状态
            if (checkboxOpts.reserve) {
                handleCheckedCheckboxRow(handleReserveRow(internalData.checkboxReserveRowMap), true, true);
            }
            if (currentRow && !fullAllDataRowIdData[getRowid($xeTable, currentRow)]) {
                internalData.currentRow = null; // 刷新当前行状态
            }
            // 行展开
            internalData.rowExpandedMaps = expandColumn ? getRecoverRowMaps(rowExpandedMaps) : {}; // 刷新行展开状态
            reactData.rowExpandedFlag++;
            // 还原保留状态
            if (expandColumn && expandOpts.reserve) {
                $xeTable.setRowExpand(handleReserveRow(internalData.rowExpandedReserveRowMap), true);
            }
            // 树展开
            internalData.treeExpandedMaps = treeConfig ? getRecoverRowMaps(treeExpandedMaps) : {}; // 刷新树展开状态
            reactData.treeExpandedFlag++;
            if (treeConfig && treeOpts.reserve) {
                $xeTable.setTreeExpand(handleReserveRow(internalData.treeExpandedReserveRowMap), true);
            }
        };
        /**
         * 处理默认展开树节点
         */
        const handleDefaultTreeExpand = () => {
            const { treeConfig } = props;
            if (treeConfig) {
                const { fullAllDataRowIdData } = internalData;
                const treeOpts = computeTreeOpts.value;
                const { expandAll, expandRowKeys } = treeOpts;
                if (expandAll) {
                    $xeTable.setAllTreeExpand(true);
                }
                else if (expandRowKeys) {
                    const defExpandeds = [];
                    expandRowKeys.forEach((rowKey) => {
                        const rowid = encodeRowid(rowKey);
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            defExpandeds.push(rowRest.row);
                        }
                    });
                    $xeTable.setTreeExpand(defExpandeds, true);
                }
            }
        };
        const handleAsyncTreeExpandChilds = (row) => {
            const treeOpts = computeTreeOpts.value;
            const checkboxOpts = computeCheckboxOpts.value;
            const { transform, loadMethod } = treeOpts;
            const { checkStrictly } = checkboxOpts;
            return new Promise(resolve => {
                if (loadMethod) {
                    const { fullAllDataRowIdData, treeExpandLazyLoadedMaps } = internalData;
                    const rowid = getRowid($xeTable, row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    treeExpandLazyLoadedMaps[rowid] = row;
                    Promise.resolve(loadMethod({ $table: $xeTable, row })).then((childRecords) => {
                        if (rowRest) {
                            rowRest.treeLoaded = true;
                        }
                        if (treeExpandLazyLoadedMaps[rowid]) {
                            delete treeExpandLazyLoadedMaps[rowid];
                        }
                        if (!XEUtils.isArray(childRecords)) {
                            childRecords = [];
                        }
                        if (childRecords) {
                            return $xeTable.loadTreeChildren(row, childRecords).then(childRows => {
                                const { treeExpandedMaps } = internalData;
                                if (childRows.length && !treeExpandedMaps[rowid]) {
                                    treeExpandedMaps[rowid] = row;
                                }
                                reactData.treeExpandedFlag++;
                                // 如果当前节点已选中,则展开后子节点也被选中
                                if (!checkStrictly && $xeTable.isCheckedByCheckboxRow(row)) {
                                    handleCheckedCheckboxRow(childRows, true);
                                }
                                return nextTick().then(() => {
                                    if (transform) {
                                        $xeTable.handleTableData();
                                        updateAfterDataIndex();
                                        return nextTick();
                                    }
                                });
                            });
                        }
                    }).catch(() => {
                        const { treeExpandLazyLoadedMaps } = internalData;
                        if (rowRest) {
                            rowRest.treeLoaded = false;
                        }
                        if (treeExpandLazyLoadedMaps[rowid]) {
                            delete treeExpandLazyLoadedMaps[rowid];
                        }
                    }).finally(() => {
                        reactData.treeExpandedFlag++;
                        nextTick().then(() => $xeTable.recalculate()).then(() => resolve());
                    });
                }
                else {
                    resolve();
                }
            });
        };
        const handleTreeExpandReserve = (row, expanded) => {
            const { treeExpandedReserveRowMap } = internalData;
            const treeOpts = computeTreeOpts.value;
            if (treeOpts.reserve) {
                const rowid = getRowid($xeTable, row);
                if (expanded) {
                    treeExpandedReserveRowMap[rowid] = row;
                }
                else if (treeExpandedReserveRowMap[rowid]) {
                    delete treeExpandedReserveRowMap[rowid];
                }
            }
        };
        const handleAsyncRowExpand = (row) => {
            return new Promise(resolve => {
                const expandOpts = computeExpandOpts.value;
                const { loadMethod } = expandOpts;
                if (loadMethod) {
                    const { fullAllDataRowIdData, rowExpandLazyLoadedMaps } = internalData;
                    const rowid = getRowid($xeTable, row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    rowExpandLazyLoadedMaps[rowid] = row;
                    loadMethod({ $table: $xeTable, row, rowIndex: $xeTable.getRowIndex(row), $rowIndex: $xeTable.getVMRowIndex(row) }).then(() => {
                        const { rowExpandedMaps } = internalData;
                        if (rowRest) {
                            rowRest.expandLoaded = true;
                        }
                        rowExpandedMaps[rowid] = row;
                        reactData.rowExpandedFlag++;
                    }).catch(() => {
                        if (rowRest) {
                            rowRest.expandLoaded = false;
                        }
                    }).finally(() => {
                        const { rowExpandLazyLoadedMaps } = internalData;
                        if (rowExpandLazyLoadedMaps[rowid]) {
                            delete rowExpandLazyLoadedMaps[rowid];
                        }
                        reactData.rowExpandedFlag++;
                        nextTick()
                            .then(() => $xeTable.recalculate())
                            .then(() => $xeTable.updateCellAreas())
                            .then(() => resolve());
                    });
                }
                else {
                    resolve();
                }
            });
        };
        const handleRowExpandReserve = (row, expanded) => {
            const { rowExpandedReserveRowMap } = internalData;
            const expandOpts = computeExpandOpts.value;
            if (expandOpts.reserve) {
                const rowid = getRowid($xeTable, row);
                if (expanded) {
                    rowExpandedReserveRowMap[rowid] = row;
                }
                else if (rowExpandedReserveRowMap[rowid]) {
                    delete rowExpandedReserveRowMap[rowid];
                }
            }
        };
        const handleDefaultMergeCells = () => {
            const { mergeCells } = props;
            if (mergeCells) {
                $xeTable.setMergeCells(mergeCells);
            }
        };
        const handleDefaultMergeHeaderItems = () => {
            const { mergeHeaderCells } = props;
            if (mergeHeaderCells) {
                $xeTable.setMergeHeaderCells(mergeHeaderCells);
            }
        };
        const handleDefaultMergeFooterItems = () => {
            const { mergeFooterCells, mergeFooterItems } = props;
            const mFooterCells = mergeFooterCells || mergeFooterItems;
            if (mFooterCells) {
                $xeTable.setMergeFooterCells(mFooterCells);
            }
        };
        // 计算可视渲染相关数据
        const computeScrollLoad = () => {
            return nextTick().then(() => {
                const { scrollXLoad, scrollYLoad } = reactData;
                const { scrollXStore, scrollYStore } = internalData;
                const virtualYOpts = computeVirtualYOpts.value;
                const virtualXOpts = computeVirtualXOpts.value;
                // 计算 X 逻辑
                if (scrollXLoad) {
                    const { toVisibleIndex: toXVisibleIndex, visibleSize: visibleXSize } = handleVirtualXVisible();
                    const offsetXSize = Math.max(0, virtualXOpts.oSize ? XEUtils.toNumber(virtualXOpts.oSize) : 0);
                    scrollXStore.preloadSize = XEUtils.toNumber(virtualXOpts.preSize);
                    scrollXStore.offsetSize = offsetXSize;
                    scrollXStore.visibleSize = visibleXSize;
                    scrollXStore.endIndex = Math.max(scrollXStore.startIndex + scrollXStore.visibleSize + offsetXSize, scrollXStore.endIndex);
                    scrollXStore.visibleStartIndex = Math.max(scrollXStore.startIndex, toXVisibleIndex);
                    scrollXStore.visibleEndIndex = Math.min(scrollXStore.endIndex, toXVisibleIndex + visibleXSize);
                    $xeTable.updateScrollXData().then(() => {
                        loadScrollXData();
                    });
                }
                else {
                    $xeTable.updateScrollXSpace();
                }
                // 计算 Y 逻辑
                const rowHeight = computeRowHeight();
                scrollYStore.rowHeight = rowHeight; // 已废弃
                reactData.rowHeight = rowHeight;
                const { toVisibleIndex: toYVisibleIndex, visibleSize: visibleYSize } = handleVirtualYVisible();
                if (scrollYLoad) {
                    const offsetYSize = Math.max(0, virtualYOpts.oSize ? XEUtils.toNumber(virtualYOpts.oSize) : 0);
                    scrollYStore.preloadSize = XEUtils.toNumber(virtualYOpts.preSize);
                    scrollYStore.offsetSize = offsetYSize;
                    scrollYStore.visibleSize = visibleYSize;
                    scrollYStore.endIndex = Math.max(scrollYStore.startIndex + visibleYSize + offsetYSize, scrollYStore.endIndex);
                    scrollYStore.visibleStartIndex = Math.max(scrollYStore.startIndex, toYVisibleIndex);
                    scrollYStore.visibleEndIndex = Math.min(scrollYStore.endIndex, toYVisibleIndex + visibleYSize);
                    $xeTable.updateScrollYData().then(() => {
                        loadScrollYData();
                    });
                }
                else {
                    $xeTable.updateScrollYSpace();
                }
            });
        };
        const calcScrollbar = () => {
            const { scrollXWidth, scrollYHeight } = reactData;
            const { elemStore } = internalData;
            const scrollbarOpts = computeScrollbarOpts.value;
            const el = refElem.value;
            if (!el || !el.clientWidth) {
                return;
            }
            const bodyWrapperElem = getRefElem(elemStore['main-body-wrapper']);
            const headerTableElem = getRefElem(elemStore['main-header-table']);
            const footerTableElem = getRefElem(elemStore['main-footer-table']);
            const xHandleEl = refScrollXHandleElem.value;
            const yHandleEl = refScrollYHandleElem.value;
            let overflowY = false;
            let overflowX = false;
            if (bodyWrapperElem) {
                overflowY = scrollYHeight > bodyWrapperElem.clientHeight;
                if (yHandleEl) {
                    reactData.scrollbarWidth = scrollbarOpts.width || (yHandleEl.offsetWidth - yHandleEl.clientWidth) || 14;
                }
                reactData.overflowY = overflowY;
                overflowX = scrollXWidth > bodyWrapperElem.clientWidth;
                if (xHandleEl) {
                    reactData.scrollbarHeight = scrollbarOpts.height || (xHandleEl.offsetHeight - xHandleEl.clientHeight) || 14;
                }
                const hHeight = headerTableElem ? headerTableElem.clientHeight : 0;
                const fHeight = footerTableElem ? footerTableElem.clientHeight : 0;
                internalData.tableHeight = bodyWrapperElem.offsetHeight;
                internalData.tHeaderHeight = hHeight;
                internalData.tFooterHeight = fHeight;
                reactData.overflowX = overflowX;
                reactData.parentHeight = Math.max(hHeight + fHeight + 20, $xeTable.getParentHeight());
            }
            if (overflowX) {
                $xeTable.checkScrolling();
            }
        };
        const handleRecalculateStyle = (reFull, reWidth, reHeight) => {
            const el = refElem.value;
            if (!el || !el.clientWidth) {
                return nextTick();
            }
            const varEl = refVarElem.value;
            if (varEl) {
                const [defEl, mediumEl, smallEl, miniEl] = varEl.children;
                calcVarRowHeightConfig('default', defEl);
                calcVarRowHeightConfig('medium', mediumEl);
                calcVarRowHeightConfig('small', smallEl);
                calcVarRowHeightConfig('mini', miniEl);
            }
            if (reWidth) {
                calcCellWidth();
            }
            if (reWidth || reFull) {
                autoCellWidth();
            }
            calcScrollbar();
            updateStyle();
            updateRowExpandStyle();
            if (reFull) {
                updateTreeLineStyle();
            }
            internalData.rceRunTime = Date.now();
            return computeScrollLoad().then(() => {
                // 初始化时需要在列计算之后再执行优化运算,达到最优显示效果
                if (reWidth) {
                    calcCellWidth();
                }
                if (reWidth || reFull) {
                    autoCellWidth();
                }
                if (reHeight) {
                    calcCellHeight();
                }
                updateStyle();
                calcScrollbar();
                if (reFull) {
                    updateRowOffsetTop();
                }
                updateRowExpandStyle();
                if (reFull) {
                    updateTreeLineStyle();
                }
                internalData.rceRunTime = Date.now();
                if (reFull) {
                    return computeScrollLoad();
                }
            });
        };
        const defaultMinRunDelay = 50;
        const handleLazyRecalculate = (reFull, reWidth, reHeight, options) => {
            const minRunDelay = (options ? options.minRunDelay : defaultMinRunDelay) || defaultMinRunDelay;
            return new Promise(resolve => {
                const $xeGanttView = internalData.xeGanttView;
                const { customStore, tableData, tableColumn } = reactData;
                const { rceTimeout, rceRunTime } = internalData;
                const resizeOpts = computeResizeOpts.value;
                let rceDelay = internalData.rceDelay;
                // 如果在500毫秒内频繁执行,则执行次数减缓
                if (rceRunTime && rceRunTime > Date.now() - 500) {
                    rceDelay = Math.min(Math.max(60, Math.min(800, tableData.length / 8)), rceDelay + 50);
                }
                else {
                    rceDelay = 0;
                }
                internalData.rceDelay = rceDelay;
                const refreshDelay = resizeOpts.refreshDelay || 30;
                const reDelay = rceDelay + refreshDelay;
                const el = refElem.value;
                if (el && el.clientWidth) {
                    autoCellWidth();
                    updateRowExpandStyle();
                }
                if (customStore.visible && $xeTable.handleCustomStyle) {
                    $xeTable.handleCustomStyle();
                }
                const renderCellSize = tableData.length * tableColumn.length;
                // 渲染量低的场景
                if (renderCellSize < 400) {
                    rceDelay = 20;
                }
                else if (renderCellSize < 600) {
                    rceDelay = 40;
                }
                else if (renderCellSize < 800) {
                    rceDelay = 80;
                }
                if (rceTimeout) {
                    clearTimeout(rceTimeout);
                    // 多少毫秒内至少执行一次
                    if (rceRunTime && rceRunTime + minRunDelay < Date.now()) {
                        resolve(handleRecalculateStyle(reFull, reWidth, reHeight));
                    }
                    else {
                        nextTick(() => {
                            resolve();
                        });
                    }
                }
                else {
                    resolve(handleRecalculateStyle(reFull, reWidth, reHeight));
                }
                if ($xeGanttView && $xeGanttView.handleLazyRecalculate) {
                    $xeGanttView.handleLazyRecalculate();
                }
                internalData.rceTimeout = setTimeout(() => {
                    internalData.rceDelay = 0;
                    internalData.rceTimeout = undefined;
                    handleRecalculateStyle(reFull, reWidth, reHeight);
                    if ($xeGanttView && $xeGanttView.handleLazyRecalculate) {
                        $xeGanttView.handleLazyRecalculate();
                    }
                }, reDelay);
            });
        };
        const handleResizeEvent = () => {
            if (internalData.rsePending) {
                return;
            }
            internalData.rsePending = true;
            handleLazyRecalculate(true, true, true, {
                minRunDelay: 200
            }).then(() => {
                internalData.rsePending = false;
            }).catch(() => {
                internalData.rsePending = false;
            });
        };
        const handleUpdateAggValues = () => {
            const { visibleColumn } = internalData;
            const aggCols = [];
            visibleColumn.forEach(column => {
                if (column.aggFunc) {
                    aggCols.push(column);
                }
            });
            reactData.aggHandleAggColumns = aggCols;
        };
        const handleUpdateRowGroup = (groupFields) => {
            const aggGroupFields = [];
            const aggGroupConfs = [];
            if (groupFields) {
                (XEUtils.isArray(groupFields) ? groupFields : [groupFields]).forEach(field => {
                    aggGroupFields.push(field);
                    aggGroupConfs.push({
                        field
                    });
                });
            }
            reactData.rowGroupList = aggGroupConfs;
            reactData.aggHandleFields = aggGroupFields;
            handleUpdateAggValues();
        };
        const handleeGroupSummary = (aggList) => {
            const { fullColumnFieldData } = internalData;
            const aggregateOpts = computeAggregateOpts.value;
            const aggFuncColumns = computeAggFuncColumns.value;
            const { mapChildrenField } = aggregateOpts;
            const aggCalcMethod = aggregateOpts.calcValuesMethod || aggregateOpts.countMethod || aggregateOpts.aggregateMethod;
            if (mapChildrenField) {
                XEUtils.lastEach(aggList, aggRow => {
                    let count = 0;
                    XEUtils.each(aggRow[mapChildrenField], (row) => {
                        if (row.isAggregate) {
                            count += row.childCount || 0;
                        }
                        else {
                            count++;
                        }
                    });
                    aggRow.childCount = count;
                });
                if ($xeTable.handlePivotTableAggData) {
                    $xeTable.handlePivotTableAggData(aggList);
                }
                else {
                    if (aggFuncColumns.length) {
                        XEUtils.lastEach(aggList, aggRow => {
                            const aggDtObj = {};
                            const aggData = aggRow.aggData;
                            const groupField = aggRow.groupField;
                            const groupContent = aggRow.groupContent;
                            const childList = mapChildrenField ? (aggRow[mapChildrenField] || []) : [];
                            const childCount = aggRow.childCount;
                            const colRest = fullColumnFieldData[groupField] || {};
                            aggFuncColumns.forEach(column => {
                                const { field } = column;
                                const currAggData = aggData ? aggData[field] : null;
                                const ctParams = {
                                    $table: $xeTable,
                                    groupField,
                                    groupColumn: (colRest ? colRest.column : null),
                                    column,
                                    groupValue: groupContent,
                                    childList,
                                    childCount,
                                    aggValue: currAggData ? currAggData.value : 0,
                                    /**
                                   * 已废弃
                                   * @deprecated
                                   */
                                    children: childList,
                                    /**
                                   * 已废弃
                                   * @deprecated
                                   */
                                    totalValue: childCount
                                };
                                let aggVal = 0;
                                // 如果下层同时也是分组
                                if (childList.length && childList[0].isAggregate) {
                                    XEUtils.each(childList, (row) => {
                                        if (row.isAggregate) {
                                            const currAggData = row.aggData[field];
                                            if (currAggData) {
                                                aggVal += currAggData.value;
                                            }
                                        }
                                    });
                                }
                                else {
                                    aggVal = aggCalcMethod ? aggCalcMethod(ctParams) : aggRow.childCount;
                                }
                                aggDtObj[field] = {
                                    type: 'count',
                                    value: aggVal,
                                    label: aggVal
                                };
                            });
                            aggRow.aggData = aggDtObj;
                        });
                    }
                }
            }
        };
        const updateGroupData = () => {
            const { aggregateConfig, rowGroupConfig } = props;
            const { isRowGroupStatus } = reactData;
            const { tableFullGroupData } = internalData;
            const aggregateOpts = computeAggregateOpts.value;
            const { mapChildrenField } = aggregateOpts;
            if ((aggregateConfig || rowGroupConfig) && isRowGroupStatus) {
                const aggList = [];
                XEUtils.eachTree(tableFullGroupData, row => {
                    if (row.isAggregate) {
                        aggList.push(row);
                    }
                }, { children: mapChildrenField });
                handleeGroupSummary(aggList);
            }
        };
        const handleGroupData = (list, rowGroups, isCombinedField) => {
            let fullData = list;
            let treeData = list;
            if (rowGroups) {
                const aggregateOpts = computeAggregateOpts.value;
                const { rowField, parentField, separator, childrenField, mapChildrenField } = aggregateOpts;
                const rowOpts = computeRowOpts.value;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField } = checkboxOpts;
                const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField;
                const rgItem = rowGroups[0];
                if (rgItem && rowField && parentField && childrenField && mapChildrenField) {
                    fullData = [];
                    treeData = [];
                    const groupField = rgItem.field;
                    const groupColumn = $xeTable.getColumnByField(groupField);
                    const groupMaps = {};
                    const groupCombinedMaps = {};
                    const aggList = [];
                    const rowkey = getRowkey($xeTable);
                    list.forEach((row) => {
                        const cellValue = groupColumn ? $xeTable.getCellLabel(row, groupColumn) : XEUtils.get(row, groupField);
                        let groupValue = XEUtils.eqNull(cellValue) ? '' : cellValue;
                        if (isCombinedField) {
                            const groupVals = [groupValue];
                            rowGroups.slice(1).forEach(ogItem => {
                                const ogField = ogItem.field;
                                const ogColumn = $xeTable.getColumnByField(ogField);
                                const ocValue = ogColumn ? $xeTable.getCellLabel(row, ogColumn) : XEUtils.get(row, ogField);
                                const ogValue = XEUtils.eqNull(ocValue) ? '' : ocValue;
                                groupValue += (separator || ' / ') + ogValue;
                                groupVals.push(ogValue);
                            });
                            if (!groupCombinedMaps[groupValue]) {
                                groupCombinedMaps[groupValue] = groupVals;
                            }
                        }
                        let childList = groupMaps[groupValue];
                        if (!childList) {
                            childList = [];
                            groupMaps[groupValue] = childList;
                        }
                        if (row.isAggregate) {
                            row.isAggregate = undefined;
                        }
                        childList.push(row);
                    });
                    if (isCombinedField) {
                        XEUtils.objectEach(groupMaps, (childList, groupValue) => {
                            const aggRow = {
                                isAggregate: true,
                                aggData: {},
                                groupContent: groupValue,
                                groupCombineds: groupCombinedMaps[groupValue],
                                groupField,
                                childCount: 0,
                                [rowField]: getRowUniqueId(),
                                [parentField]: null,
                                [childrenField]: childList,
                                [mapChildrenField]: childList
                            };
                            aggRow[rowkey] = createRowId(rowOpts, aggRow, rowkey);
                            if (checkField) {
                                aggRow[checkField] = false;
                            }
                            if (indeterminateField) {
                                aggRow[indeterminateField] = false;
                            }
                            aggList.push(aggRow);
                            treeData.push(aggRow);
                            fullData.push(aggRow);
                        });
                    }
                    else {
                        XEUtils.objectEach(groupMaps, (childList, groupValue) => {
                            const { fullData: childFullData, treeData: childTreeData } = handleGroupData(childList, rowGroups.slice(1));
                            const aggRow = {
                                isAggregate: true,
                                aggData: {},
                                groupContent: groupValue,
                                groupCombineds: [],
                                groupField,
                                childCount: 0,
                                [rowField]: getRowUniqueId(),
                                [parentField]: null,
                                [childrenField]: childTreeData,
                                [mapChildrenField]: childTreeData
                            };
                            aggRow[rowkey] = createRowId(rowOpts, aggRow, rowkey);
                            if (checkField) {
                                aggRow[checkField] = false;
                            }
                            if (indeterminateField) {
                                aggRow[indeterminateField] = false;
                            }
                            aggList.push(aggRow);
                            treeData.push(aggRow);
                            fullData.push(aggRow);
                            if (childFullData.length) {
                                fullData.push(...childFullData);
                            }
                        });
                    }
                    handleeGroupSummary(aggList);
                }
            }
            return {
                treeData,
                fullData
            };
        };
        const initGroupData = (list, rowGroups) => {
            const aggregateOpts = computeAggregateOpts.value;
            const { mode } = aggregateOpts;
            const isCombinedField = mode === 'combined';
            const groupRest = handleGroupData(list, rowGroups, isCombinedField);
            return groupRest;
        };
        const initData = () => {
            const { data } = props;
            loadTableData(data || [], true, true).then(() => {
                if (data && data.length) {
                    internalData.inited = true;
                    internalData.initStatus = true;
                    handleLoadDefaults();
                }
                handleInitDefaults();
                updateStyle();
                if (!reactData.isAllOverflow) {
                    calcCellHeight();
                    updateRowOffsetTop();
                }
            });
            nextTick(() => {
                dispatchEvent('ready', {}, null);
            });
        };
        /**
         * 加载表格数据
         * @param {Array} datas 数据
         */
        const loadTableData = (datas, isReload, isReset) => {
            const { keepSource, treeConfig, rowGroupConfig, aggregateConfig } = props;
            const { rowGroupList, scrollYLoad: oldScrollYLoad } = reactData;
            const { initStatus, scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop } = internalData;
            const rowOpts = computeRowOpts.value;
            const treeOpts = computeTreeOpts.value;
            const expandOpts = computeExpandOpts.value;
            const { transform } = treeOpts;
            const childrenField = treeOpts.children || treeOpts.childrenField;
            let treeData = [];
            let fullData = reactive(datas ? datas.slice(0) : []); // 转为响应式数据
            if (fullData.length > supportMaxRow) {
                errLog('vxe.error.errMaxRow', [supportMaxRow]);
            }
            if (treeConfig && rowGroupList.length) {
                errLog('vxe.error.noTree', ['aggregate-config']);
                return nextTick();
            }
            if (rowOpts.drag && rowGroupList.length) {
                errLog('vxe.error.errConflicts', ['row-config.drag', 'aggregate-config']);
                return nextTick();
            }
            let isRGroup = false;
            if (treeConfig) {
                if (transform) {
                    // 树结构自动转换
                    if (!treeOpts.rowField) {
                        errLog('vxe.error.reqProp', ['tree-config.rowField']);
                    }
                    if (!treeOpts.parentField) {
                        errLog('vxe.error.reqProp', ['tree-config.parentField']);
                    }
                    if (!childrenField) {
                        errLog('vxe.error.reqProp', ['tree-config.childrenField']);
                    }
                    if (!treeOpts.mapChildrenField) {
                        errLog('vxe.error.reqProp', ['tree-config.mapChildrenField']);
                    }
                    if (childrenField === treeOpts.mapChildrenField) {
                        errLog('vxe.error.errConflicts', ['tree-config.childrenField', 'tree-config.mapChildrenField']);
                    }
                    // fullData.forEach(row => {
                    //   if (row[treeOpts.children] && row[treeOpts.children].length) {
                    //     warnLog('vxe.error.errConflicts', ['tree-config.transform', `row.${treeOpts.children}`])
                    //   }
                    // })
                    treeData = XEUtils.toArrayTree(fullData, {
                        key: treeOpts.rowField,
                        parentKey: treeOpts.parentField,
                        children: childrenField,
                        mapChildren: treeOpts.mapChildrenField
                    });
                    fullData = treeData.slice(0);
                }
                else {
                    treeData = fullData.slice(0);
                }
            }
            else if ((aggregateConfig || rowGroupConfig) && rowGroupList.length) {
                const groupRest = initGroupData(fullData, rowGroupList);
                treeData = groupRest.treeData;
                fullData = groupRest.fullData;
                isRGroup = true;
            }
            reactData.isRowGroupStatus = isRGroup;
            scrollYStore.startIndex = 0;
            scrollYStore.endIndex = 1;
            scrollXStore.startIndex = 0;
            scrollXStore.endIndex = 1;
            internalData.cvCacheMaps = {};
            reactData.isRowLoading = true;
            reactData.scrollVMLoading = false;
            reactData.treeExpandedFlag++;
            reactData.rowExpandedFlag++;
            internalData.insertRowMaps = {};
            reactData.insertRowFlag++;
            internalData.removeRowMaps = {};
            reactData.removeRowFlag++;
            internalData.fullCellHeightMaps = {};
            internalData.fullCellStoreMaps = {};
            const sYLoad = updateScrollYStatus(fullData);
            // 全量数据
            internalData.tableFullData = fullData;
            internalData.tableFullTreeData = isRGroup ? [] : treeData;
            internalData.tableFullGroupData = isRGroup ? treeData : [];
            // 缓存数据
            $xeTable.cacheRowMap(isReset);
            // 原始数据
            internalData.tableSynchData = datas;
            if (isReset) {
                internalData.isResizeCellHeight = false;
            }
            // 克隆原数据,用于显示编辑状态,与编辑值做对比
            if (keepSource) {
                $xeTable.cacheSourceMap(fullData);
            }
            if ($xeTable.clearCellAreas && props.mouseConfig) {
                $xeTable.clearCellAreas();
                $xeTable.clearCopyCellArea();
            }
            $xeTable.clearMergeCells();
            $xeTable.clearMergeFooterItems();
            $xeTable.clearHistory();
            $xeTable.handleTableData(true);
            $xeTable.updateFooter();
            $xeTable.handleUpdateBodyMerge();
            return nextTick().then(() => {
                updateHeight();
                updateStyle();
            }).then(() => {
                computeScrollLoad();
                syncGanttScrollYStatus();
            }).then(() => {
                const virtualYOpts = computeVirtualYOpts.value;
                // 是否启用了虚拟滚动
                if (sYLoad) {
                    scrollYStore.endIndex = scrollYStore.visibleSize;
                }
                if (sYLoad) {
                    if (reactData.expandColumn && expandOpts.mode !== 'fixed') {
                        errLog('vxe.error.notConflictProp', ['column.type="expand', 'expand-config.mode="fixed"']);
                    }
                    if (virtualYOpts.mode === 'scroll' && reactData.expandColumn && expandOpts.mode === 'fixed') {
                        warnLog('vxe.error.notConflictProp', ['virtual-y-config.mode=scroll', 'expand-config.mode=inside']);
                    }
                    // if (showOverflow) {
                    //   if (!rowOpts.height) {
                    //     const errColumn = internalData.tableFullColumn.find(column => column.showOverflow === false)
                    //     if (errColumn) {
                    //       errLog('vxe.error.errProp', [`column[field="${errColumn.field}"].show-overflow=false`, 'show-overflow=true'])
                    //     }
                    //   }
                    // }
                    if (!(props.height || props.maxHeight)) {
                        errLog('vxe.error.reqSupportProp', ['virtual-y-config.enabled = true', 'height | max-height']);
                    }
                    // if (!props.showOverflow) {
                    //   warnLog('vxe.error.reqProp', ['table.show-overflow'])
                    // }
                    // if (props.spanMethod) {
                    //   warnLog('vxe.error.scrollErrProp', ['span-method'])
                    // }
                }
                handleReserveStatus();
                $xeTable.checkSelectionStatus();
                $xeTable.dispatchEvent('data-change', {
                    visibleColumn: internalData.visibleColumn,
                    visibleData: internalData.afterFullData
                }, null);
                return new Promise(resolve => {
                    nextTick()
                        .then(() => handleRecalculateStyle(false, false, false))
                        .then(() => {
                        handleRecalculateStyle(false, true, true);
                        updateRowOffsetTop();
                    })
                        .then(() => {
                        let targetScrollLeft = lastScrollLeft;
                        let targetScrollTop = lastScrollTop;
                        const virtualXOpts = computeVirtualXOpts.value;
                        const virtualYOpts = computeVirtualYOpts.value;
                        // 是否在更新数据之后自动滚动重置滚动条
                        if (virtualXOpts.scrollToLeftOnChange) {
                            targetScrollLeft = 0;
                        }
                        if (virtualYOpts.scrollToTopOnChange) {
                            targetScrollTop = 0;
                        }
                        reactData.isRowLoading = false;
                        handleRecalculateStyle(false, false, false);
                        updateTreeLineStyle();
                        syncGanttScrollYStatus();
                        // 如果是自动行高,特殊情况需调用 recalculate 手动刷新
                        if (!props.showOverflow) {
                            setTimeout(() => {
                                handleLazyRecalculate(false, true, true);
                                setTimeout(() => handleLazyRecalculate(false, true, true), 3000);
                            }, 2000);
                        }
                        // 是否变更虚拟滚动
                        if (oldScrollYLoad === sYLoad) {
                            restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
                                .then(() => {
                                handleRecalculateStyle(false, true, true);
                                updateRowOffsetTop();
                                updateTreeLineStyle();
                                nextTick(() => resolve());
                            });
                        }
                        else {
                            setTimeout(() => {
                                restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
                                    .then(() => {
                                    handleRecalculateStyle(false, true, true);
                                    updateRowOffsetTop();
                                    updateTreeLineStyle();
                                    nextTick(() => resolve());
                                });
                            });
                        }
                    });
                }).then(() => {
                    if (initStatus) {
                        dispatchEvent('data-rendered', {
                            isReload,
                            visibleColumn: internalData.visibleColumn,
                            visibleData: internalData.afterFullData
                        }, null);
                    }
                    else {
                        dispatchEvent('init-rendered', {
                            visibleColumn: internalData.visibleColumn,
                            visibleData: internalData.afterFullData
                        }, null);
                    }
                });
            });
        };
        /**
         * 处理数据加载默认行为
         * 默认执行一次,除非被重置
         */
        const handleLoadDefaults = () => {
            handleDefaultSelectionChecked();
            handleDefaultRadioChecked();
            handleDefaultRowExpand();
            handleDefaultTreeExpand();
            handleDefaultRowGroupExpand();
            handleDefaultMergeCells();
            handleDefaultMergeHeaderItems();
            handleDefaultMergeFooterItems();
            nextTick(() => {
                setTimeout(() => $xeTable.recalculate());
            });
        };
        /**
         * 处理初始化的默认行为
         * 只会执行一次
         */
        const handleInitDefaults = () => {
            handleDefaultSort();
        };
        const handleTableColumn = () => {
            const { scrollXLoad } = reactData;
            const { visibleColumn, scrollXStore, fullColumnIdData } = internalData;
            const tableColumn = scrollXLoad ? visibleColumn.slice(scrollXStore.startIndex, scrollXStore.endIndex) : visibleColumn.slice(0);
            tableColumn.forEach((column, $index) => {
                const colid = column.id;
                const colRest = fullColumnIdData[colid];
                if (colRest) {
                    colRest.$index = $index;
                }
            });
            reactData.tableColumn = tableColumn;
        };
        const handleUpdateColumn = () => {
            const columnList = XEUtils.orderBy(internalData.collectColumn, 'renderSortNumber');
            internalData.collectColumn = columnList;
            const tFullColumn = getColumnList(columnList);
            internalData.tableFullColumn = tFullColumn;
            reactData.updateColFlag++;
            cacheColumnMap();
        };
        const loadScrollXData = () => {
            const { isScrollXBig } = reactData;
            const { mergeBodyList, mergeFooterList, mergeBodyRowMaps, scrollXStore } = internalData;
            const { preloadSize, startIndex, endIndex, offsetSize } = scrollXStore;
            const { toVisibleIndex, visibleSize } = handleVirtualXVisible();
            const offsetItem = {
                startIndex: Math.max(0, isScrollXBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
                endIndex: isScrollXBig ? toVisibleIndex + visibleSize : toVisibleIndex + visibleSize + offsetSize + preloadSize
            };
            scrollXStore.visibleStartIndex = toVisibleIndex - 1;
            scrollXStore.visibleEndIndex = toVisibleIndex + visibleSize + 1;
            calculateMergerOffsetIndex(mergeBodyList.concat(mergeFooterList), mergeBodyRowMaps, offsetItem, 'col');
            const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem;
            if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
                if (startIndex !== offsetStartIndex || endIndex !== offsetEndIndex) {
                    scrollXStore.startIndex = offsetStartIndex;
                    scrollXStore.endIndex = offsetEndIndex;
                    $xeTable.updateScrollXData();
                }
            }
            $xeTable.closeTooltip();
        };
        const parseColumns = (isReset) => {
            // const { showOverflow } = props
            // const rowOpts = computeRowOpts.value
            const leftList = [];
            const centerList = [];
            const rightList = [];
            const { isGroup, columnStore } = reactData;
            const { collectColumn, tableFullColumn, scrollXStore, fullColumnIdData } = internalData;
            // 如果是分组表头,如果子列全部被隐藏,则根列也隐藏
            if (isGroup) {
                const leftGroupList = [];
                const centerGroupList = [];
                const rightGroupList = [];
                XEUtils.eachTree(collectColumn, (column, index, items, path, parentColumn) => {
                    const isColGroup = hasChildrenList(column);
                    // 如果是分组,必须按组设置固定列,不允许给子列设置固定
                    if (parentColumn && parentColumn.fixed) {
                        column.fixed = parentColumn.fixed;
                    }
                    if (parentColumn && (column.fixed || '') !== (parentColumn.fixed || '')) {
                        errLog('vxe.error.groupFixed');
                    }
                    if (isColGroup) {
                        column.visible = !!XEUtils.findTree(column.children, (subColumn) => hasChildrenList(subColumn) ? false : subColumn.visible);
                    }
                    else if (column.visible) {
                        if (column.fixed === 'left') {
                            leftList.push(column);
                        }
                        else if (column.fixed === 'right') {
                            rightList.push(column);
                        }
                        else {
                            centerList.push(column);
                        }
                    }
                });
                collectColumn.forEach((column) => {
                    if (column.visible) {
                        if (column.fixed === 'left') {
                            leftGroupList.push(column);
                        }
                        else if (column.fixed === 'right') {
                            rightGroupList.push(column);
                        }
                        else {
                            centerGroupList.push(column);
                        }
                    }
                });
                reactData.tableGroupColumn = leftGroupList.concat(centerGroupList).concat(rightGroupList);
            }
            else {
                // 重新分配列
                tableFullColumn.forEach((column) => {
                    if (column.visible) {
                        if (column.fixed === 'left') {
                            leftList.push(column);
                        }
                        else if (column.fixed === 'right') {
                            rightList.push(column);
                        }
                        else {
                            centerList.push(column);
                        }
                    }
                });
            }
            const visibleColumn = leftList.concat(centerList).concat(rightList);
            internalData.visibleColumn = visibleColumn;
            updateColumnOffsetLeft();
            const sXLoad = updateScrollXStatus();
            reactData.hasFixedColumn = leftList.length > 0 || rightList.length > 0;
            Object.assign(columnStore, { leftList, centerList, rightList });
            if (sXLoad) {
                // if (showOverflow) {
                //   if (!rowOpts.height) {
                //     const errColumn = internalData.tableFullColumn.find(column => column.showOverflow === false)
                //     if (errColumn) {
                //       errLog('vxe.error.errProp', [`column[field="${errColumn.field}"].show-overflow=false`, 'show-overflow=true'])
                //     }
                //   }
                // }
                // if (props.showHeader && !props.showHeaderOverflow) {
                //   warnLog('vxe.error.reqProp', ['show-header-overflow'])
                // }
                // if (props.showFooter && !props.showFooterOverflow) {
                //   warnLog('vxe.error.reqProp', ['show-footer-overflow'])
                // }
                if (props.spanMethod) {
                    warnLog('vxe.error.scrollErrProp', ['span-method']);
                }
                if (props.footerSpanMethod) {
                    warnLog('vxe.error.scrollErrProp', ['footer-span-method']);
                }
                if (isReset) {
                    const { visibleSize } = handleVirtualXVisible();
                    scrollXStore.startIndex = 0;
                    scrollXStore.endIndex = visibleSize;
                    scrollXStore.visibleSize = visibleSize;
                    scrollXStore.visibleStartIndex = 0;
                    scrollXStore.visibleEndIndex = visibleSize;
                }
            }
            // 如果列被显示/隐藏,则清除合并状态
            // 如果列被设置为固定,则清除合并状态
            if (visibleColumn.length !== internalData.visibleColumn.length || !internalData.visibleColumn.every((column, index) => column === visibleColumn[index])) {
                $xeTable.clearMergeCells();
                $xeTable.clearMergeFooterItems();
            }
            visibleColumn.forEach((column, index) => {
                const colid = column.id;
                const colRest = fullColumnIdData[colid];
                if (colRest) {
                    colRest._index = index;
                }
            });
            handleTableColumn();
            handleUpdateAggValues();
            if (isReset) {
                updateColumnOffsetLeft();
                return $xeTable.updateFooter().then(() => {
                    return $xeTable.recalculate();
                }).then(() => {
                    $xeTable.updateCellAreas();
                    return $xeTable.recalculate();
                });
            }
            return $xeTable.updateFooter();
        };
        const initColumnHierarchy = () => {
            const { collectColumn } = internalData;
            const fullColIdData = {};
            const fullColFieldData = {};
            let sortIndex = 1;
            XEUtils.eachTree(collectColumn, (column, index, items, path, parentColumn) => {
                const { id: colid, field } = column;
                const parentId = parentColumn ? parentColumn.id : null;
                const rest = { $index: -1, _index: -1, column, colid, index, items, parent: parentColumn || null, width: 0, oLeft: 0 };
                column.parentId = parentId;
                column.defaultParentId = parentId;
                column.sortNumber = sortIndex;
                column.renderSortNumber = sortIndex;
                sortIndex++;
                if (field) {
                    if (fullColFieldData[field]) {
                        errLog('vxe.error.colRepet', ['field', field]);
                    }
                    fullColFieldData[field] = rest;
                }
                fullColIdData[colid] = rest;
            });
            internalData.fullColumnIdData = fullColIdData;
            internalData.fullColumnFieldData = fullColFieldData;
        };
        const buildColumnInfo = () => {
            const { scrollXLoad, scrollYLoad, expandColumn } = reactData;
            const expandOpts = computeExpandOpts.value;
            cacheColumnMap();
            parseColumns(true).then(() => {
                if (reactData.scrollXLoad) {
                    loadScrollXData();
                }
            });
            $xeTable.clearHeaderFormatterCache();
            $xeTable.clearMergeCells();
            $xeTable.clearMergeFooterItems();
            $xeTable.handleTableData(true);
            $xeTable.handleAggregateSummaryData();
            if ((scrollXLoad || scrollYLoad) && (expandColumn && expandOpts.mode !== 'fixed')) {
                warnLog('vxe.error.scrollErrProp', ['column.type=expand']);
            }
            return nextTick().then(() => {
                if ($xeToolbar) {
                    $xeToolbar.syncUpdate({
                        collectColumn: internalData.collectColumn,
                        $table: $xeTable
                    });
                }
                if ($xeTable.handleUpdateCustomColumn) {
                    $xeTable.handleUpdateCustomColumn();
                }
                const columnOpts = computeColumnOpts.value;
                if (props.showCustomHeader && reactData.isGroup && (columnOpts.resizable || props.resizable)) {
                    warnLog('vxe.error.notConflictProp', ['show-custom-header & colgroup', 'column-config.resizable=false']);
                }
                reactData.isColLoading = false;
                return handleLazyRecalculate(false, true, true);
            });
        };
        const handleInitColumn = (collectColumn) => {
            internalData.collectColumn = collectColumn;
            const tFullColumn = getColumnList(collectColumn);
            internalData.tableFullColumn = tFullColumn;
            reactData.updateColFlag++;
            reactData.isColLoading = true;
            initColumnHierarchy();
            return Promise.resolve(restoreCustomStorage()).then(() => {
                return buildColumnInfo();
            });
        };
        const updateScrollXStatus = (fullColumn) => {
            const virtualXOpts = computeVirtualXOpts.value;
            const allCols = fullColumn || internalData.tableFullColumn;
            // 如果gt为0,则总是启用
            const scrollXLoad = !!virtualXOpts.enabled && virtualXOpts.gt > -1 && (virtualXOpts.gt === 0 || virtualXOpts.gt < allCols.length);
            reactData.scrollXLoad = scrollXLoad;
            return scrollXLoad;
        };
        const syncGanttScrollYStatus = () => {
            const $xeGanttView = internalData.xeGanttView;
            if ($xeGanttView && $xeGanttView.handleUpdateSYStatus) {
                $xeGanttView.handleUpdateSYStatus(reactData.scrollYLoad);
            }
        };
        const updateScrollYStatus = (fullData) => {
            const { treeConfig } = props;
            const virtualYOpts = computeVirtualYOpts.value;
            const treeOpts = computeTreeOpts.value;
            const { transform } = treeOpts;
            const allList = fullData || internalData.tableFullData;
            // 如果gt为0,则总是启用
            let scrollYLoad = !!virtualYOpts.enabled && virtualYOpts.gt > -1 && (virtualYOpts.gt === 0 || virtualYOpts.gt < allList.length);
            if (scrollYLoad && (treeConfig && !transform)) {
                errLog('vxe.error.notSupportProp', ['[table] virtual-y-config.enabled=true', 'tree-config.transform=false', 'tree-config.transform=true']);
                scrollYLoad = false;
            }
            reactData.scrollYLoad = scrollYLoad;
            syncGanttScrollYStatus();
            return scrollYLoad;
        };
        /**
         * 展开与收起树节点
         * @param rows
         * @param expanded
         * @returns
         */
        const handleBaseTreeExpand = (rows, expanded) => {
            const { treeNodeColumn } = reactData;
            const { fullAllDataRowIdData, tableFullTreeData, treeExpandedMaps, treeExpandLazyLoadedMaps } = internalData;
            const treeOpts = computeTreeOpts.value;
            const { reserve, lazy, accordion, toggleMethod } = treeOpts;
            const childrenField = treeOpts.children || treeOpts.childrenField;
            const hasChildField = treeOpts.hasChild || treeOpts.hasChildField;
            const result = [];
            const columnIndex = $xeTable.getColumnIndex(treeNodeColumn);
            const $columnIndex = $xeTable.getVMColumnIndex(treeNodeColumn);
            const _columnIndex = $xeTable.getVTColumnIndex(treeNodeColumn);
            const { handleGetRowId } = createHandleGetRowId($xeTable);
            let validRows = toggleMethod ? rows.filter((row) => toggleMethod({ $table: $xeTable, expanded, column: treeNodeColumn, columnIndex, $columnIndex, _columnIndex, row })) : rows;
            if (accordion) {
                validRows = validRows.length ? [validRows[validRows.length - 1]] : [];
                // 同一级只能展开一个
                const matchObj = XEUtils.findTree(tableFullTreeData, item => item === validRows[0], { children: childrenField });
                if (matchObj) {
                    matchObj.items.forEach(item => {
                        const rowid = handleGetRowId(item);
                        if (treeExpandedMaps[rowid]) {
                            delete treeExpandedMaps[rowid];
                        }
                    });
                }
            }
            if (expanded) {
                validRows.forEach((row) => {
                    const rowid = handleGetRowId(row);
                    if (!treeExpandedMaps[rowid]) {
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            const isLoad = lazy && row[hasChildField] && !rowRest.treeLoaded && !treeExpandLazyLoadedMaps[rowid];
                            // 是否使用懒加载
                            if (isLoad) {
                                result.push(handleAsyncTreeExpandChilds(row));
                            }
                            else {
                                if (row[childrenField] && row[childrenField].length) {
                                    treeExpandedMaps[rowid] = row;
                                }
                            }
                        }
                    }
                });
            }
            else {
                validRows.forEach(item => {
                    const rowid = handleGetRowId(item);
                    if (treeExpandedMaps[rowid]) {
                        delete treeExpandedMaps[rowid];
                    }
                });
            }
            if (reserve) {
                validRows.forEach((row) => handleTreeExpandReserve(row, expanded));
            }
            reactData.treeExpandedFlag++;
            return Promise.all(result).then(() => {
                updateTreeLineStyle();
                return $xeTable.recalculate();
            });
        };
        /**
         * 虚拟树的展开与收起
         * @param rows
         * @param expanded
         * @returns
         */
        const handleVirtualTreeExpand = (rows, expanded) => {
            const { lastScrollLeft, lastScrollTop } = internalData;
            return handleBaseTreeExpand(rows, expanded).then(() => {
                handleVirtualTreeToList();
                $xeTable.handleTableData();
                reactData.treeExpandedFlag++;
                updateAfterDataIndex();
                return nextTick();
            }).then(() => {
                return handleRecalculateStyle(true, true, true);
            }).then(() => {
                restoreScrollLocation($xeTable, lastScrollLeft, lastScrollTop);
                updateTreeLineStyle();
                setTimeout(() => {
                    $xeTable.updateCellAreas();
                }, 30);
            });
        };
        /**
         * 展开与收起行分组节点
         * @param rows
         * @param expanded
         * @returns
         */
        const handleRowGroupBaseExpand = (rows, expanded) => {
            const { fullAllDataRowIdData, tableFullGroupData, rowGroupExpandedMaps } = internalData;
            const aggregateOpts = computeAggregateOpts.value;
            const { mapChildrenField, accordion } = aggregateOpts;
            const { handleGetRowId } = createHandleGetRowId($xeTable);
            let validRows = rows;
            if (mapChildrenField) {
                if (accordion) {
                    validRows = validRows.length ? [validRows[validRows.length - 1]] : [];
                    // 同一级只能展开一个
                    const matchObj = XEUtils.findTree(tableFullGroupData, item => getRowid($xeTable, item) === getRowid($xeTable, validRows[0]), { children: mapChildrenField });
                    if (matchObj) {
                        matchObj.items.forEach(item => {
                            const rowid = handleGetRowId(item);
                            if (rowGroupExpandedMaps[rowid]) {
                                delete rowGroupExpandedMaps[rowid];
                            }
                        });
                    }
                }
                if (expanded) {
                    validRows.forEach((row) => {
                        const rowid = handleGetRowId(row);
                        if (!rowGroupExpandedMaps[rowid]) {
                            const rowRest = fullAllDataRowIdData[rowid];
                            if (rowRest) {
                                if (row[mapChildrenField] && row[mapChildrenField].length) {
                                    rowGroupExpandedMaps[rowid] = row;
                                }
                            }
                        }
                    });
                }
                else {
                    validRows.forEach(item => {
                        const rowid = handleGetRowId(item);
                        if (rowGroupExpandedMaps[rowid]) {
                            delete rowGroupExpandedMaps[rowid];
                        }
                    });
                }
            }
            reactData.rowGroupExpandedFlag++;
            return $xeTable.recalculate();
        };
        /**
         * 行分组的展开与收起
         * @param rows
         * @param expanded
         * @returns
         */
        const handleRowGroupVirtualExpand = (rows, expanded) => {
            return handleRowGroupBaseExpand(rows, expanded).then(() => {
                handleVirtualTreeToList();
                $xeTable.handleTableData();
                reactData.rowGroupExpandedFlag++;
                updateAfterDataIndex();
                return nextTick();
            }).then(() => {
                return handleLazyRecalculate(true, true, true);
            }).then(() => {
                setTimeout(() => {
                    $xeTable.updateCellAreas();
                }, 30);
            });
        };
        /**
         * 处理默认展开分组行
         */
        const handleDefaultRowGroupExpand = () => {
            const { isRowGroupStatus } = reactData;
            if (isRowGroupStatus) {
                const aggregateOpts = computeAggregateOpts.value;
                const { expandAll, expandGroupFields } = aggregateOpts;
                if (expandAll) {
                    $xeTable.setAllRowGroupExpand(true);
                }
                else if (expandGroupFields && expandGroupFields.length) {
                    $xeTable.setRowGroupExpandByField(expandGroupFields, true);
                }
            }
        };
        const handleCheckAllEvent = (evnt, value) => {
            handleCheckedAllCheckboxRow(value);
            if (evnt) {
                dispatchEvent('checkbox-all', {
                    records: () => $xeTable.getCheckboxRecords(),
                    reserves: () => $xeTable.getCheckboxReserveRecords(),
                    indeterminates: () => $xeTable.getCheckboxIndeterminateRecords(),
                    checked: value
                }, evnt);
            }
        };
        /**
         * 纵向 Y 可视渲染处理
         */
        const loadScrollYData = () => {
            const { isAllOverflow, isScrollYBig } = reactData;
            const { mergeBodyList, mergeBodyColMaps, scrollYStore } = internalData;
            const { preloadSize, startIndex, endIndex, offsetSize } = scrollYStore;
            const autoOffsetYSize = isAllOverflow ? offsetSize : offsetSize + 1;
            const { toVisibleIndex, visibleSize } = handleVirtualYVisible();
            const offsetItem = {
                startIndex: Math.max(0, isScrollYBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
                endIndex: isScrollYBig ? (toVisibleIndex + visibleSize) : (toVisibleIndex + visibleSize + autoOffsetYSize + preloadSize)
            };
            scrollYStore.visibleStartIndex = toVisibleIndex - 1;
            scrollYStore.visibleEndIndex = toVisibleIndex + visibleSize + 1;
            calculateMergerOffsetIndex(mergeBodyList, mergeBodyColMaps, offsetItem, 'row');
            const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem;
            if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
                if (startIndex !== offsetStartIndex || endIndex !== offsetEndIndex) {
                    scrollYStore.startIndex = offsetStartIndex;
                    scrollYStore.endIndex = offsetEndIndex;
                    $xeTable.updateScrollYData();
                }
            }
        };
        const createGetRowCacheProp = (prop) => {
            return function (row) {
                const { fullAllDataRowIdData } = internalData;
                if (row) {
                    const rowid = getRowid($xeTable, row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (rowRest) {
                        return rowRest[prop];
                    }
                }
                return -1;
            };
        };
        const createGetColumnCacheProp = (prop) => {
            return function (column) {
                const { fullColumnIdData } = internalData;
                if (column) {
                    const colRest = fullColumnIdData[column.id];
                    if (colRest) {
                        return colRest[prop];
                    }
                }
                return -1;
            };
        };
        const lazyScrollXData = () => {
            const { lxTimeout, lxRunTime, scrollXStore } = internalData;
            const { visibleSize } = scrollXStore;
            const fpsTime = visibleSize > 26 ? 26 : (visibleSize > 16 ? 14 : 6);
            if (lxTimeout) {
                clearTimeout(lxTimeout);
            }
            if (!lxRunTime || lxRunTime + fpsTime < Date.now()) {
                internalData.lxRunTime = Date.now();
                loadScrollXData();
            }
            internalData.lxTimeout = setTimeout(() => {
                internalData.lxTimeout = undefined;
                internalData.lxRunTime = undefined;
                loadScrollXData();
            }, fpsTime);
        };
        const lazyScrollYData = () => {
            const { lyTimeout, lyRunTime, scrollYStore } = internalData;
            const { visibleSize } = scrollYStore;
            const fpsTime = visibleSize > 30 ? 32 : (visibleSize > 20 ? 18 : 8);
            if (lyTimeout) {
                clearTimeout(lyTimeout);
            }
            if (!lyRunTime || lyRunTime + fpsTime < Date.now()) {
                internalData.lyRunTime = Date.now();
                loadScrollYData();
            }
            internalData.lyTimeout = setTimeout(() => {
                internalData.lyTimeout = undefined;
                internalData.lyRunTime = undefined;
                loadScrollYData();
            }, fpsTime);
        };
        const handleSyncScroll = (isRollX, isRollY) => {
            const { scrollXLoad, scrollYLoad, isAllOverflow } = reactData;
            const autoWidthColumnList = computeAutoWidthColumnList.value;
            internalData.lcsRunTime = Date.now();
            internalData.lcsTimeout = undefined;
            internalData.intoRunScroll = false;
            internalData.inVirtualScroll = false;
            internalData.inWheelScroll = false;
            internalData.inHeaderScroll = false;
            internalData.inBodyScroll = false;
            internalData.inFooterScroll = false;
            reactData.lazScrollLoading = false;
            internalData.scrollRenderType = '';
            let xRest = null;
            let yRest = null;
            if (!isAllOverflow) {
                calcCellHeight();
                updateRowOffsetTop();
            }
            if (isRollX && scrollXLoad) {
                xRest = $xeTable.updateScrollXData();
            }
            if (isRollY && scrollYLoad) {
                if (autoWidthColumnList.length) {
                    calcCellWidth();
                }
                yRest = $xeTable.updateScrollYData().then(() => {
                    if (autoWidthColumnList.length) {
                        calcCellWidth();
                        autoCellWidth();
                    }
                    if (!isAllOverflow) {
                        calcCellHeight();
                        updateRowOffsetTop();
                    }
                    return $xeTable.updateScrollYSpace();
                });
            }
            updateRowExpandStyle();
            return Promise.all([
                xRest,
                yRest,
                scrollXLoad || scrollYLoad ? $xeTable.updateCellAreas() : null
            ]);
        };
        const checkLastSyncScroll = (isRollX, isRollY) => {
            const { lcsTimeout } = internalData;
            reactData.lazScrollLoading = true;
            if (lcsTimeout) {
                clearTimeout(lcsTimeout);
            }
            internalData.lcsTimeout = setTimeout(() => {
                handleSyncScroll(isRollX, isRollY).then(() => {
                    if (reactData.scrollXLoad || reactData.scrollYLoad) {
                        nextTick(() => {
                            updateRowExpandStyle();
                            if (!internalData.lcsTimeout) {
                                handleSyncScroll(isRollX, isRollY);
                            }
                        });
                    }
                });
            }, 240);
        };
        const getWheelSpeed = (lastScrollTime) => {
            let multiple = 1;
            const currTime = Date.now();
            if (lastScrollTime + 25 > currTime) {
                multiple = 1.18;
            }
            else if (lastScrollTime + 30 > currTime) {
                multiple = 1.15;
            }
            else if (lastScrollTime + 40 > currTime) {
                multiple = 1.12;
            }
            else if (lastScrollTime + 55 > currTime) {
                multiple = 1.09;
            }
            else if (lastScrollTime + 75 > currTime) {
                multiple = 1.06;
            }
            else if (lastScrollTime + 100 > currTime) {
                multiple = 1.03;
            }
            return multiple;
        };
        const syncGanttScrollTop = (scrollTop) => {
            const $xeGanttView = internalData.xeGanttView;
            if ($xeGanttView) {
                const ganttInternalData = $xeGanttView.internalData;
                const { elemStore: ganttElemStore } = ganttInternalData;
                const ganttBodyScrollElem = getRefElem(ganttElemStore['main-body-scroll']);
                if (ganttBodyScrollElem) {
                    ganttBodyScrollElem.scrollTop = scrollTop;
                }
            }
        };
        const dispatchEvent = (type, params, evnt) => {
            emit(type, createEvent(evnt, { $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt }, params));
        };
        const handleScrollToRowColumn = (fieldOrColumn, row, options) => {
            const { fullColumnIdData } = internalData;
            const column = handleFieldOrColumn($xeTable, fieldOrColumn);
            if (column && fullColumnIdData[column.id]) {
                return colToVisible($xeTable, options ? options.colAlign !== false : true, column, row);
            }
            return nextTick();
        };
        const handleUpdateResize = () => {
            const el = refElem.value;
            if (el && el.clientWidth && el.clientHeight) {
                $xeTable.recalculate();
            }
        };
        const handleUpdateColResize = (evnt, params) => {
            $xeTable.analyColumnWidth();
            $xeTable.recalculate().then(() => {
                $xeTable.saveCustomStore('update:width');
                $xeTable.refreshScroll().then(() => {
                    $xeTable.updateCellAreas();
                });
                $xeTable.dispatchEvent('column-resizable-change', params, evnt);
                // 已废弃 resizable-change
                $xeTable.dispatchEvent('resizable-change', params, evnt);
                setTimeout(() => {
                    $xeTable.recalculate(true);
                }, 300);
            });
        };
        const handleUpdateRowResize = (evnt, params) => {
            reactData.resizeHeightFlag++;
            $xeTable.recalculate().then(() => {
                $xeTable.refreshScroll().then(() => {
                    $xeTable.updateCellAreas();
                });
                $xeTable.dispatchEvent('row-resizable-change', params, evnt);
                setTimeout(() => {
                    $xeTable.recalculate(true);
                }, 300);
            });
        };
        const updateColumnOffsetLeft = () => {
            const { visibleColumn, fullColumnIdData } = internalData;
            const el = refElem.value;
            if (!el || !el.clientWidth) {
                return;
            }
            let offsetLeft = 0;
            for (let cIndex = 0, rLen = visibleColumn.length; cIndex < rLen; cIndex++) {
                const column = visibleColumn[cIndex];
                const colid = column.id;
                const colRest = fullColumnIdData[colid];
                if (colRest) {
                    colRest.oLeft = offsetLeft;
                }
                offsetLeft += column.renderWidth;
            }
        };
        const updateRowOffsetTop = () => {
            const { expandColumn } = reactData;
            const { afterFullData, fullAllDataRowIdData, rowExpandedMaps } = internalData;
            const el = refElem.value;
            if (!el || !el.clientWidth) {
                return;
            }
            const expandOpts = computeExpandOpts.value;
            const rowOpts = computeRowOpts.value;
            const cellOpts = computeCellOpts.value;
            const defaultRowHeight = computeDefaultRowHeight.value;
            const { handleGetRowId } = createHandleGetRowId($xeTable);
            let offsetTop = 0;
            for (let rIndex = 0, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
                const row = afterFullData[rIndex];
                const rowid = handleGetRowId(row);
                const rowRest = fullAllDataRowIdData[rowid] || {};
                rowRest.oTop = offsetTop;
                offsetTop += getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                // 是否展开行
                if (expandColumn && rowExpandedMaps[rowid]) {
                    offsetTop += rowRest.expandHeight || expandOpts.height || 0;
                }
            }
        };
        /**
         * 更新展开行样式
         */
        const updateRowExpandStyle = () => {
            const { expandColumn, scrollYLoad, scrollYTop, isScrollYBig } = reactData;
            const el = refElem.value;
            if (!el || !el.clientWidth) {
                return;
            }
            const expandOpts = computeExpandOpts.value;
            const { mode } = expandOpts;
            if (expandColumn && mode === 'fixed') {
                const { elemStore, fullAllDataRowIdData } = internalData;
                const rowOpts = computeRowOpts.value;
                const cellOpts = computeCellOpts.value;
                const defaultRowHeight = computeDefaultRowHeight.value;
                const rowExpandEl = refRowExpandElem.value;
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                if (rowExpandEl && bodyScrollElem) {
                    let isUpdateHeight = false;
                    XEUtils.arrayEach(rowExpandEl.children, reEl => {
                        const expandEl = reEl;
                        const rowid = expandEl.getAttribute('rowid') || '';
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            const expandHeight = expandEl.offsetHeight;
                            const trEl = bodyScrollElem.querySelector(`.vxe-body--row[rowid="${rowid}"]`);
                            let offsetTop = 0;
                            if (scrollYLoad) {
                                if (isScrollYBig && trEl) {
                                    offsetTop = trEl.offsetTop + trEl.offsetHeight;
                                }
                                else {
                                    offsetTop = rowRest.oTop + getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                                }
                            }
                            else {
                                if (trEl) {
                                    offsetTop = trEl.offsetTop + trEl.offsetHeight;
                                }
                            }
                            if (isScrollYBig) {
                                offsetTop += scrollYTop;
                            }
                            expandEl.style.top = toCssUnit(offsetTop);
                            if (!isUpdateHeight) {
                                if (rowRest.expandHeight !== expandHeight) {
                                    isUpdateHeight = true;
                                }
                            }
                            rowRest.expandHeight = expandHeight;
                        }
                    });
                    if (isUpdateHeight) {
                        reactData.rowExpandHeightFlag++;
                        nextTick(() => {
                            updateRowOffsetTop();
                        });
                    }
                }
            }
        };
        /**
         * 更新树连接线样式
         */
        const updateTreeLineStyle = () => {
            const { treeConfig } = props;
            if (!treeConfig) {
                return;
            }
            const { tableData } = reactData;
            const { fullAllDataRowIdData, treeExpandedMaps } = internalData;
            const el = refElem.value;
            if (!el || !el.clientWidth) {
                return;
            }
            const cellOpts = computeCellOpts.value;
            const rowOpts = computeRowOpts.value;
            const defaultRowHeight = computeDefaultRowHeight.value;
            const treeOpts = computeTreeOpts.value;
            const { transform, mapChildrenField } = treeOpts;
            const childrenField = treeOpts.children || treeOpts.childrenField;
            const { handleGetRowId } = createHandleGetRowId($xeTable);
            const expParentList = [];
            const handleNodeRow = (row, rIndex, rows) => {
                const rowid = handleGetRowId(row);
                const rowRest = fullAllDataRowIdData[rowid] || {};
                const childList = row[transform ? mapChildrenField : childrenField];
                const prevRow = rows[rIndex - 1] || null;
                const nextRow = rows[rIndex + 1] || null;
                if (childList && childList.length && treeExpandedMaps[rowid]) {
                    expParentList.push({ row, prevRow, nextRow });
                    childList.forEach((childRow, crIndex) => {
                        const childRowid = handleGetRowId(childRow);
                        if (treeExpandedMaps[childRowid]) {
                            handleNodeRow(childRow, crIndex, childList);
                        }
                    });
                }
                else {
                    if (nextRow) {
                        const nextRowid = handleGetRowId(nextRow);
                        const nextRowRest = fullAllDataRowIdData[nextRowid] || {};
                        const currCellHeight = getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                        const nextCellHeight = getCellRestHeight(nextRowRest, cellOpts, rowOpts, defaultRowHeight);
                        rowRest.oHeight = currCellHeight;
                        rowRest.lineHeight = Math.floor(currCellHeight / 2 + nextCellHeight / 2);
                    }
                    else {
                        rowRest.oHeight = 0;
                        rowRest.lineHeight = 0;
                    }
                }
            };
            tableData.forEach((row, rIndex) => {
                handleNodeRow(row, rIndex, tableData);
            });
            XEUtils.lastArrayEach(expParentList, ({ row, nextRow }) => {
                const rowid = handleGetRowId(row);
                const childList = row[transform ? mapChildrenField : childrenField];
                const rowRest = fullAllDataRowIdData[rowid];
                if (rowRest) {
                    const currCellHeight = getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                    let countOffsetHeight = currCellHeight;
                    let countLineHeight = 0;
                    childList.forEach((childRow) => {
                        const childRowid = handleGetRowId(childRow);
                        const childRowRest = fullAllDataRowIdData[childRowid] || {};
                        const childList = childRow[transform ? mapChildrenField : childrenField];
                        if (treeExpandedMaps[childRowid] && childList && childList.length) {
                            countOffsetHeight += (childRowRest.oHeight || 0);
                            countLineHeight += (childRowRest.oHeight || 0);
                        }
                        else {
                            const cellHeight = getCellRestHeight(childRowRest, cellOpts, rowOpts, defaultRowHeight);
                            childRowRest.oHeight = cellHeight;
                            childRowRest.lineHeight = cellHeight;
                            countOffsetHeight += cellHeight;
                            countLineHeight += cellHeight;
                        }
                    });
                    if (nextRow) {
                        const nextRowid = handleGetRowId(nextRow);
                        const nextRowRest = fullAllDataRowIdData[nextRowid] || {};
                        const currCellHeight = getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                        const nextCellHeight = getCellRestHeight(nextRowRest, cellOpts, rowOpts, defaultRowHeight);
                        countOffsetHeight += currCellHeight;
                        countLineHeight += Math.floor(currCellHeight / 2 + nextCellHeight / 2);
                    }
                    rowRest.lineHeight = countLineHeight;
                    rowRest.oHeight = countOffsetHeight;
                }
            });
        };
        const handleRowExpandScroll = () => {
            const { elemStore } = internalData;
            const rowExpandEl = refRowExpandElem.value;
            const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
            if (rowExpandEl && bodyScrollElem) {
                rowExpandEl.scrollTop = bodyScrollElem.scrollTop;
            }
        };
        const handleColumnVisible = (visible) => {
            return function (fieldOrColumn) {
                let status = false;
                const cols = XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : [fieldOrColumn];
                cols.forEach(item => {
                    const column = handleFieldOrColumn($xeTable, item);
                    if (column) {
                        if (column.children && column.children.length) {
                            XEUtils.eachTree([column], (item) => {
                                item.visible = visible;
                                item.renderVisible = visible;
                            });
                        }
                        else {
                            column.visible = visible;
                            column.renderVisible = visible;
                        }
                        if (!status) {
                            status = true;
                        }
                    }
                });
                if (status) {
                    return $xeTable.handleCustom();
                }
                return nextTick();
            };
        };
        tableMethods = {
            dispatchEvent,
            getEl() {
                return refElem.value;
            },
            /**
             * 重置表格的一切数据状态
             */
            clearAll() {
                return clearTableAllStatus($xeTable);
            },
            /**
             * 同步 data 数据(即将废弃)
             * 如果用了该方法,那么组件将不再记录增删改的状态,只能自行实现对应逻辑
             * 对于某些特殊的场景,比如深层树节点元素发生变动时可能会用到
             */
            syncData() {
                errLog('vxe.error.delFunc', ['syncData', 'getData']);
                return nextTick().then(() => {
                    reactData.tableData = [];
                    emit('update:data', internalData.tableFullData);
                    return nextTick();
                });
            },
            /**
             * 手动处理数据,用于手动排序与筛选
             * 对于手动更改了排序、筛选...等条件后需要重新处理数据时可能会用到
             */
            updateData() {
                const { scrollXLoad, scrollYLoad } = reactData;
                return $xeTable.handleTableData(true).then(() => {
                    $xeTable.updateFooter();
                    if (scrollXLoad || scrollYLoad) {
                        if (scrollXLoad) {
                            $xeTable.updateScrollXSpace();
                        }
                        if (scrollYLoad) {
                            $xeTable.updateScrollYSpace();
                        }
                        return $xeTable.refreshScroll();
                    }
                }).then(() => {
                    $xeTable.updateCellAreas();
                    return handleLazyRecalculate(true, true, true);
                }).then(() => {
                    // 存在滚动行为未结束情况
                    setTimeout(() => handleLazyRecalculate(false, true, true), 50);
                });
            },
            /**
             * 重新加载数据,不会清空表格状态
             * @param {Array} datas 数据
             */
            loadData(datas) {
                const { initStatus } = internalData;
                return loadTableData(datas, false, false).then(() => {
                    internalData.inited = true;
                    internalData.initStatus = true;
                    if (!initStatus) {
                        handleLoadDefaults();
                    }
                    return handleLazyRecalculate(false, true, true);
                });
            },
            /**
             * 重新加载数据,会清空表格状态
             * @param {Array} datas 数据
             */
            reloadData(datas) {
                return $xeTable.clearAll()
                    .then(() => {
                    internalData.inited = true;
                    internalData.initStatus = true;
                    return loadTableData(datas, true, true);
                }).then(() => {
                    handleLoadDefaults();
                    return handleLazyRecalculate(false, true, true);
                });
            },
            /**
             * 修改行数据
             */
            setRow(rows, record) {
                if (rows && record) {
                    let rest = rows;
                    if (!XEUtils.isArray(rows)) {
                        rest = [rows];
                    }
                    const rowkey = getRowkey($xeTable);
                    rest.forEach(row => {
                        const rowid = getRowid($xeTable, row);
                        const newRecord = XEUtils.clone(Object.assign({}, record), true);
                        XEUtils.set(newRecord, rowkey, rowid);
                        Object.assign(row, newRecord);
                    });
                }
                return nextTick();
            },
            /**
             * 局部加载行数据并恢复到初始状态
             * 对于行数据需要局部更改的场景中可能会用到
             * @param {Row} row 行对象
             * @param {Object} record 新数据
             * @param {String} field 字段名
             */
            reloadRow(row, record, field) {
                const { keepSource } = props;
                const { tableData } = reactData;
                const { sourceDataRowIdData } = internalData;
                if (keepSource) {
                    if ($xeTable.isAggregateRecord(row)) {
                        return nextTick();
                    }
                    const rowkey = getRowkey($xeTable);
                    const rowid = XEUtils.get(row, rowkey);
                    const oRow = sourceDataRowIdData[rowid];
                    if (oRow && row) {
                        if (field) {
                            const newValue = XEUtils.clone(XEUtils.get(record || row, field), true);
                            XEUtils.set(row, field, newValue);
                            XEUtils.set(oRow, field, newValue);
                        }
                        else {
                            const newRecord = XEUtils.clone(Object.assign({}, record), true);
                            XEUtils.set(newRecord, rowkey, rowid);
                            XEUtils.destructuring(oRow, Object.assign(row, newRecord));
                        }
                    }
                    reactData.tableData = tableData.slice(0);
                }
                else {
                    errLog('vxe.error.reqProp', ['keep-source']);
                }
                return nextTick();
            },
            getParams() {
                return props.params;
            },
            /**
             * 用于树结构,给行数据加载子节点
             */
            loadTreeChildren(row, childRecords) {
                const { keepSource } = props;
                const { tableSourceData, fullDataRowIdData, fullAllDataRowIdData, sourceDataRowIdData } = internalData;
                const treeOpts = computeTreeOpts.value;
                const { transform, mapChildrenField } = treeOpts;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const parentRest = fullAllDataRowIdData[getRowid($xeTable, row)];
                const parentLevel = parentRest ? parentRest.level : 0;
                return $xeTable.createData(childRecords).then((rows) => {
                    if (keepSource) {
                        const rowid = getRowid($xeTable, row);
                        const matchObj = XEUtils.findTree(tableSourceData, (item) => rowid === getRowid($xeTable, item), { children: childrenField });
                        if (matchObj) {
                            matchObj.item[childrenField] = XEUtils.clone(rows, true);
                        }
                        rows.forEach(childRow => {
                            const rowid = getRowid($xeTable, childRow);
                            sourceDataRowIdData[rowid] = XEUtils.clone(childRow, true);
                        });
                    }
                    XEUtils.eachTree(rows, (childRow, index, items, path, parentItem, nodes) => {
                        const rowid = getRowid($xeTable, childRow);
                        const parentRow = parentItem || parentRest.row;
                        const rest = { row: childRow, rowid, _seq: -1, seq: -1, index, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items, parent: parentRow, level: parentLevel + nodes.length, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 };
                        fullDataRowIdData[rowid] = rest;
                        fullAllDataRowIdData[rowid] = rest;
                    }, { children: childrenField });
                    row[childrenField] = rows;
                    if (transform) {
                        row[mapChildrenField] = XEUtils.clone(rows, false);
                    }
                    updateAfterDataIndex();
                    return rows;
                });
            },
            /**
             * 加载列配置
             * 对于表格列需要重载、局部递增场景下可能会用到
             * @param {ColumnInfo} columns 列配置
             */
            loadColumn(columns) {
                const { lastScrollLeft, lastScrollTop } = internalData;
                const collectColumn = XEUtils.mapTree(columns, column => reactive(Cell.createColumn($xeTable, column)));
                return handleInitColumn(collectColumn).then(() => {
                    let targetScrollLeft = lastScrollLeft;
                    let targetScrollTop = lastScrollTop;
                    const virtualXOpts = computeVirtualXOpts.value;
                    const virtualYOpts = computeVirtualYOpts.value;
                    // 是否在更新数据之后自动滚动重置滚动条
                    if (virtualXOpts.scrollToLeftOnChange) {
                        targetScrollLeft = 0;
                    }
                    if (virtualYOpts.scrollToTopOnChange) {
                        targetScrollTop = 0;
                    }
                    restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop);
                });
            },
            /**
             * 加载列配置并恢复到初始状态
             * 对于表格列需要重载、局部递增场景下可能会用到
             * @param {ColumnInfo} columns 列配置
             */
            reloadColumn(columns) {
                return $xeTable.clearAll().then(() => {
                    return $xeTable.loadColumn(columns);
                });
            },
            /**
             * 根据 tr 元素获取对应的 row 信息
             * @param {Element} tr 元素
             */
            getRowNode(tr) {
                if (tr) {
                    const { fullAllDataRowIdData } = internalData;
                    const rowid = tr.getAttribute('rowid');
                    if (rowid) {
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            return {
                                rowid: rowRest.rowid,
                                item: rowRest.row,
                                index: rowRest.index,
                                items: rowRest.items,
                                parent: rowRest.parent
                            };
                        }
                    }
                }
                return null;
            },
            /**
             * 根据 th/td 元素获取对应的 column 信息
             * @param {Element} cell 元素
             */
            getColumnNode(cell) {
                if (cell) {
                    const { fullColumnIdData } = internalData;
                    const colid = cell.getAttribute('colid');
                    if (colid) {
                        const colRest = fullColumnIdData[colid];
                        if (colRest) {
                            return {
                                colid: colRest.colid,
                                item: colRest.column,
                                index: colRest.index,
                                items: colRest.items,
                                parent: colRest.parent
                            };
                        }
                    }
                }
                return null;
            },
            /**
             * 根据 row 获取序号
             * @param {Row} row 行对象
             */
            getRowSeq: createGetRowCacheProp('seq'),
            /**
             * 根据 row 获取相对于 data 中的索引
             * @param {Row} row 行对象
             */
            getRowIndex: createGetRowCacheProp('index'),
            /**
             * 根据 row 获取相对于当前数据中的索引
             * @param {Row} row 行对象
             */
            getVTRowIndex: createGetRowCacheProp('_index'),
            /**
             * 根据 row 获取渲染中的虚拟索引
             * @param {Row} row 行对象
             */
            getVMRowIndex: createGetRowCacheProp('$index'),
            /**
             * 根据 column 获取相对于 columns 中的索引
             * @param {ColumnInfo} column 列配置
             */
            getColumnIndex: createGetColumnCacheProp('index'),
            /**
             * 根据 column 获取相对于当前表格列中的索引
             * @param {ColumnInfo} column 列配置
             */
            getVTColumnIndex: createGetColumnCacheProp('_index'),
            /**
             * 根据 column 获取渲染中的虚拟索引
             * @param {ColumnInfo} column 列配置
             */
            getVMColumnIndex: createGetColumnCacheProp('$index'),
            /**
             * 创建 data 对象
             * 对于某些特殊场景可能会用到,会自动对数据的字段名进行检测,如果不存在就自动定义
             * @param {Array} records 新数据
             */
            createData(records) {
                return nextTick().then(() => {
                    return reactive($xeTable.defineField(records));
                });
            },
            /**
             * 创建 Row|Rows 对象
             * 对于某些特殊场景需要对数据进行手动插入时可能会用到
             * @param {Array/Object} records 新数据
             */
            createRow(records) {
                const isArr = XEUtils.isArray(records);
                if (!isArr) {
                    records = [records || {}];
                }
                return $xeTable.createData(records).then((rows) => isArr ? rows : rows[0]);
            },
            /**
             * 还原数据
             * 如果不传任何参数,则还原整个表格
             * 如果传 row 则还原一行
             * 如果传 rows 则还原多行
             * 如果还额外传了 field 则还原指定的单元格数据
             */
            revertData(rows, field) {
                const { keepSource, treeConfig } = props;
                const { fullAllDataRowIdData, fullDataRowIdData, tableSourceData, sourceDataRowIdData, tableFullData, afterFullData, removeRowMaps } = internalData;
                const treeOpts = computeTreeOpts.value;
                const { transform } = treeOpts;
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                if (!keepSource) {
                    errLog('vxe.error.reqProp', ['keep-source']);
                    return nextTick();
                }
                let targetRows = rows;
                if (rows) {
                    if (!XEUtils.isArray(rows)) {
                        targetRows = [rows];
                    }
                }
                else {
                    targetRows = XEUtils.toArray($xeTable.getUpdateRecords());
                }
                let reDelFlag = false;
                if (targetRows.length) {
                    targetRows.forEach((item) => {
                        const rowid = handleGetRowId(item);
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            const row = rowRest.row;
                            if (!$xeTable.isInsertByRow(row)) {
                                const oRow = sourceDataRowIdData[rowid];
                                if (oRow && row) {
                                    if (field) {
                                        XEUtils.set(row, field, XEUtils.clone(XEUtils.get(oRow, field), true));
                                    }
                                    else {
                                        XEUtils.destructuring(row, XEUtils.clone(oRow, true));
                                    }
                                    if (!fullDataRowIdData[rowid] && $xeTable.isRemoveByRow(row)) {
                                        if (removeRowMaps[rowid]) {
                                            delete removeRowMaps[rowid];
                                        }
                                        tableFullData.unshift(row);
                                        afterFullData.unshift(row);
                                        reDelFlag = true;
                                    }
                                }
                            }
                        }
                    });
                }
                if (rows) {
                    if (reDelFlag) {
                        reactData.removeRowFlag++;
                        $xeTable.updateFooter();
                        $xeTable.cacheRowMap(false);
                        $xeTable.handleTableData(treeConfig && transform);
                        if (!(treeConfig && transform)) {
                            $xeTable.updateAfterDataIndex();
                        }
                        $xeTable.checkSelectionStatus();
                        if (reactData.scrollYLoad) {
                            $xeTable.updateScrollYSpace();
                        }
                    }
                    return nextTick().then(() => {
                        $xeTable.updateCellAreas();
                        return handleLazyRecalculate(false, true, true);
                    });
                }
                return $xeTable.reloadData(tableSourceData);
            },
            /**
             * 清空单元格内容
             * 如果不创参数,则清空整个表格内容
             * 如果传 row 则清空一行内容
             * 如果传 rows 则清空多行内容
             * 如果还额外传了 field 则清空指定单元格内容
             * @param {Array/Row} rows 行数据
             * @param {String} field 字段名
             */
            clearData(rows, field) {
                const { tableFullData, visibleColumn } = internalData;
                if (!arguments.length) {
                    rows = tableFullData;
                }
                else if (rows && !XEUtils.isArray(rows)) {
                    rows = [rows];
                }
                if (field) {
                    rows.forEach((row) => XEUtils.set(row, field, null));
                }
                else {
                    rows.forEach((row) => {
                        visibleColumn.forEach((column) => {
                            if (column.field) {
                                setCellValue(row, column, null);
                            }
                        });
                    });
                }
                return nextTick();
            },
            effectCellData(row, column, options) {
                const { fullCellStoreMaps } = internalData;
                const editOpts = computeEditOpts.value;
                const { key, isChanged, setValue, getResult } = options;
                const rowid = getRowid($xeTable, row);
                const colid = column.id;
                let rowStore = fullCellStoreMaps[rowid];
                const cellValue = XEUtils.get(row, column.field);
                const restParams = {
                    $table: $xeTable,
                    row,
                    rowid,
                    column,
                    colid,
                    cellValue,
                    oldValue: null
                };
                if (editOpts.cache === false && key === 'render_table_cell') {
                    const rest = restParams;
                    rest.cellResult = getResult ? getResult(restParams) : cellValue;
                    return rest;
                }
                if (!rowStore) {
                    rowStore = {};
                    fullCellStoreMaps[rowid] = rowStore;
                }
                let cellStore = rowStore[colid];
                if (!cellStore) {
                    cellStore = {
                        value: undefined,
                        result: {}
                    };
                    rowStore[colid] = cellStore;
                }
                const restData = rowStore[colid];
                const oldValue = restData.value;
                restParams.oldValue = oldValue;
                if (isChanged ? !isChanged(restParams) : oldValue !== cellValue) {
                    restData.value = setValue ? setValue(restParams) : cellValue;
                    restData.result = {};
                }
                const storeData = restData.result;
                if (XEUtils.isUndefined(storeData[key])) {
                    storeData[key] = getResult ? getResult(restParams) : cellValue;
                }
                const cellResult = storeData[key];
                const rest = restParams;
                rest.cellResult = cellResult;
                return rest;
            },
            getCellElement(row, fieldOrColumn) {
                const { elemStore } = internalData;
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (!column) {
                    return null;
                }
                const rowid = getRowid($xeTable, row);
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const leftScrollElem = getRefElem(elemStore['left-body-scroll']);
                const rightScrollElem = getRefElem(elemStore['right-body-scroll']);
                let bodyElem;
                if (column) {
                    if (column.fixed) {
                        if (column.fixed === 'left') {
                            if (leftScrollElem) {
                                bodyElem = leftScrollElem;
                            }
                        }
                        else {
                            if (rightScrollElem) {
                                bodyElem = rightScrollElem;
                            }
                        }
                    }
                    if (!bodyElem) {
                        bodyElem = bodyScrollElem;
                    }
                    if (bodyElem) {
                        return bodyElem.querySelector(`.vxe-body--row[rowid="${rowid}"] .${column.id}`);
                    }
                }
                return null;
            },
            getCellLabel(row, fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (!column) {
                    return null;
                }
                const { editConfig } = props;
                const { formatter, editRender, cellRender } = column;
                let etOpSize = null;
                let etOgSize = null;
                let clOpSize = null;
                let clOgSize = null;
                if (editRender) {
                    etOpSize = editRender.options ? editRender.options.length : 0;
                    etOgSize = editRender.optionGroups ? editRender.optionGroups.length : 0;
                }
                if (cellRender) {
                    clOpSize = cellRender.options ? cellRender.options.length : 0;
                    clOgSize = cellRender.optionGroups ? cellRender.optionGroups.length : 0;
                }
                // formatter > tableCellFormatter
                const renderOpts = formatter ? null : (editConfig && isEnableConf(editRender) ? editRender : (isEnableConf(cellRender) ? cellRender : null));
                const compConf = renderOpts ? renderer.get(renderOpts.name) : null;
                const tcFormatter = compConf ? compConf.tableCellFormatter : null;
                const cellValue = getCellValue(row, column);
                let cellLabel = cellValue;
                if (formatter || tcFormatter) {
                    let formatData;
                    const { fullAllDataRowIdData } = internalData;
                    const rowid = getRowid($xeTable, row);
                    const colid = column.id;
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (rowRest) {
                        formatData = rowRest.formatData;
                        if (!formatData) {
                            formatData = fullAllDataRowIdData[rowid].formatData = {};
                        }
                        if (rowRest && formatData[colid]) {
                            const ftValue = formatData[colid].value;
                            if (ftValue && ftValue[0] === cellValue && ftValue[1] === etOpSize && ftValue[2] === etOgSize && ftValue[3] === clOpSize && ftValue[4] === clOgSize) {
                                return formatData[colid].label;
                            }
                        }
                    }
                    const formatParams = {
                        $table: $xeTable,
                        cellValue,
                        row,
                        rowIndex: $xeTable.getRowIndex(row),
                        column,
                        columnIndex: $xeTable.getColumnIndex(column)
                    };
                    if (formatter) {
                        if (XEUtils.isString(formatter)) {
                            const gFormatOpts = formats.get(formatter);
                            const tcFormatMethod = gFormatOpts ? (gFormatOpts.tableCellFormatMethod || gFormatOpts.cellFormatMethod) : null;
                            cellLabel = tcFormatMethod ? tcFormatMethod(formatParams) : '';
                        }
                        else if (XEUtils.isArray(formatter)) {
                            const gFormatOpts = formats.get(formatter[0]);
                            const tcFormatMethod = gFormatOpts ? (gFormatOpts.tableCellFormatMethod || gFormatOpts.cellFormatMethod) : null;
                            cellLabel = tcFormatMethod ? tcFormatMethod(formatParams, ...formatter.slice(1)) : '';
                        }
                        else {
                            cellLabel = formatter(formatParams);
                        }
                    }
                    else if (renderOpts && tcFormatter) {
                        cellLabel = tcFormatter(renderOpts, formatParams);
                    }
                    if (formatData) {
                        const ftValue = [cellValue, etOpSize, etOgSize, clOpSize, clOgSize];
                        formatData[colid] = { value: ftValue, label: cellLabel };
                    }
                }
                return cellLabel;
            },
            updateCellLabel(row, fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (!column) {
                    return null;
                }
                const { fullAllDataRowIdData } = internalData;
                const rowid = getRowid($xeTable, row);
                if (rowid) {
                    const colid = column.id;
                    const rowid = getRowid($xeTable, row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (rowRest) {
                        const formatData = rowRest.formatData;
                        if (formatData) {
                            delete formatData[colid];
                        }
                    }
                }
                return $xeTable.getFooterCellLabel(row, column);
            },
            clearFormatterCache(isUpdate) {
                const { tableData, tableColumn } = reactData;
                const { fullAllDataRowIdData } = internalData;
                XEUtils.each(fullAllDataRowIdData, (rowRest) => {
                    if (rowRest.formatData) {
                        rowRest.formatData = undefined;
                    }
                });
                if (isUpdate) {
                    tableData.forEach(row => {
                        tableColumn.forEach(column => {
                            $xeTable.getCellLabel(row, column);
                        });
                    });
                }
                return nextTick();
            },
            getHeaderCellLabel(fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (!column) {
                    return null;
                }
                const { headerFormatter } = column;
                const _columnIndex = $xeTable.getVTColumnIndex(column);
                let cellLabel = column.getTitle();
                if (headerFormatter) {
                    let formatData;
                    const { headerFullDataColData } = internalData;
                    const colid = column.id;
                    let colRest = headerFullDataColData[colid];
                    if (!colRest) {
                        colRest = headerFullDataColData[colid] = {};
                    }
                    const formatObj = colRest.formatObj;
                    if (formatObj && formatObj.value === cellLabel) {
                        return formatObj.label;
                    }
                    const headFormatParams = {
                        $table: $xeTable,
                        cellTitle: cellLabel,
                        cellValue: cellLabel,
                        column,
                        _columnIndex,
                        columnIndex: $xeTable.getColumnIndex(column)
                    };
                    if (XEUtils.isString(headerFormatter)) {
                        const gFormatOpts = formats.get(headerFormatter);
                        const fcFormatMethod = gFormatOpts ? gFormatOpts.tableHeaderCellFormatMethod : null;
                        cellLabel = XEUtils.toValueString(fcFormatMethod ? fcFormatMethod(headFormatParams) : '');
                    }
                    else if (XEUtils.isArray(headerFormatter)) {
                        const gFormatOpts = formats.get(headerFormatter[0]);
                        const fcFormatMethod = gFormatOpts ? gFormatOpts.tableHeaderCellFormatMethod : null;
                        cellLabel = XEUtils.toValueString(fcFormatMethod ? fcFormatMethod(headFormatParams, ...headerFormatter.slice(1)) : '');
                    }
                    else {
                        cellLabel = XEUtils.toValueString(headerFormatter(headFormatParams));
                    }
                    if (formatData) {
                        colRest.formatObj = { value: cellLabel, label: cellLabel };
                    }
                }
                return cellLabel;
            },
            updateHeaderCellLabel(fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (!column) {
                    return '';
                }
                const { headerFullDataColData } = internalData;
                const colid = column.id;
                const colRest = headerFullDataColData[colid];
                if (colRest) {
                    colRest.formatObj = undefined;
                }
                return $xeTable.getHeaderCellLabel(column);
            },
            clearHeaderFormatterCache(isUpdate) {
                const { tableColumn } = reactData;
                const { headerFullDataColData } = internalData;
                XEUtils.each(headerFullDataColData, (colRest) => {
                    if (colRest.formatObj) {
                        colRest.formatObj = undefined;
                    }
                });
                if (isUpdate) {
                    tableColumn.forEach(column => {
                        $xeTable.getHeaderCellLabel(column);
                    });
                }
                return nextTick();
            },
            getFooterCellLabel(row, fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (!column) {
                    return null;
                }
                const { footerFormatter } = column;
                const _columnIndex = $xeTable.getVTColumnIndex(column);
                let itemValue = '';
                // 兼容老模式
                if (XEUtils.isArray(row)) {
                    itemValue = row[_columnIndex];
                }
                else {
                    itemValue = XEUtils.get(row, column.field);
                }
                let cellLabel = itemValue;
                if (footerFormatter) {
                    let formatData;
                    const { footerTableData } = reactData;
                    const { footerFullDataRowData } = internalData;
                    const colid = column.id;
                    const $rowIndex = footerTableData.indexOf(row);
                    let rowRest = null;
                    if ($rowIndex > -1) {
                        rowRest = footerFullDataRowData[$rowIndex];
                        if (!rowRest) {
                            rowRest = footerFullDataRowData[$rowIndex] = {};
                        }
                        formatData = rowRest.formatData;
                        if (!formatData) {
                            formatData = footerFullDataRowData[$rowIndex].formatData = {};
                        }
                        if (rowRest && formatData[colid]) {
                            if (formatData[colid].value === itemValue) {
                                return formatData[colid].label;
                            }
                        }
                    }
                    const footerFormatParams = {
                        $table: $xeTable,
                        cellValue: itemValue,
                        itemValue,
                        row,
                        items: row,
                        $rowIndex,
                        column,
                        _columnIndex,
                        columnIndex: $xeTable.getColumnIndex(column)
                    };
                    if (XEUtils.isString(footerFormatter)) {
                        const gFormatOpts = formats.get(footerFormatter);
                        const fcFormatMethod = gFormatOpts ? gFormatOpts.tableFooterCellFormatMethod : null;
                        cellLabel = fcFormatMethod ? fcFormatMethod(footerFormatParams) : '';
                    }
                    else if (XEUtils.isArray(footerFormatter)) {
                        const gFormatOpts = formats.get(footerFormatter[0]);
                        const fcFormatMethod = gFormatOpts ? gFormatOpts.tableFooterCellFormatMethod : null;
                        cellLabel = fcFormatMethod ? fcFormatMethod(footerFormatParams, ...footerFormatter.slice(1)) : '';
                    }
                    else {
                        cellLabel = footerFormatter(footerFormatParams);
                    }
                    if (formatData) {
                        formatData[colid] = { value: itemValue, label: cellLabel };
                    }
                }
                return cellLabel;
            },
            updateFooterCellLabel(row, fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (!column) {
                    return null;
                }
                const { footerTableData } = reactData;
                const { footerFullDataRowData } = internalData;
                const colid = column.id;
                const $rowIndex = footerTableData.indexOf(row);
                const rowRest = footerFullDataRowData[$rowIndex];
                if (rowRest) {
                    const formatData = rowRest.formatData;
                    if (formatData) {
                        delete formatData[colid];
                    }
                }
                return $xeTable.getFooterCellLabel(row, column);
            },
            clearFooterFormatterCache(isUpdate) {
                const { tableData, tableColumn } = reactData;
                const { footerFullDataRowData } = internalData;
                XEUtils.each(footerFullDataRowData, (rowRest) => {
                    if (rowRest.formatData) {
                        rowRest.formatData = undefined;
                    }
                });
                if (isUpdate) {
                    tableData.forEach(row => {
                        tableColumn.forEach(column => {
                            $xeTable.getFooterCellLabel(row, column);
                        });
                    });
                }
                return nextTick();
            },
            /**
             * 检查是否为临时行数据
             */
            isInsertByRow(row) {
                const rowid = getRowid($xeTable, row);
                return !!reactData.insertRowFlag && !!internalData.insertRowMaps[rowid];
            },
            isRemoveByRow(row) {
                const rowid = getRowid($xeTable, row);
                return !!reactData.removeRowFlag && !!internalData.removeRowMaps[rowid];
            },
            /**
             * 删除所有新增的临时数据
             */
            removeInsertRow() {
                const { insertRowMaps } = internalData;
                return $xeTable.remove(XEUtils.values(insertRowMaps));
            },
            /**
             * 检查行或列数据是否发生改变
             */
            isUpdateByRow(rowidOrRow, field) {
                const { keepSource } = props;
                const { fullDataRowIdData, sourceDataRowIdData } = internalData;
                const keepFields = computeKeepFields.value;
                if (keepSource) {
                    const rowid = XEUtils.isString(rowidOrRow) || XEUtils.isNumber(rowidOrRow) ? rowidOrRow : getRowid($xeTable, rowidOrRow);
                    const rowRest = fullDataRowIdData[rowid];
                    // 新增的数据不需要检测
                    if (!rowRest) {
                        return false;
                    }
                    const row = rowRest.row;
                    const oRow = sourceDataRowIdData[rowid];
                    if (!oRow) {
                        return false;
                    }
                    if (arguments.length > 1) {
                        return !eqCellValue(row, oRow, field).result;
                    }
                    for (let i = 0; i < keepFields.length; i++) {
                        if (!eqCellValue(row, oRow, keepFields[i]).result) {
                            return true;
                        }
                    }
                }
                return false;
            },
            getUpdateCells() {
                const { keepSource, treeConfig } = props;
                const { tableFullData, tableFullTreeData, fullDataRowIdData, sourceDataRowIdData, fullColumnFieldData } = internalData;
                const treeOpts = computeTreeOpts.value;
                const keepFields = computeKeepFields.value;
                const cellList = [];
                if (keepSource) {
                    const { handleGetRowId } = createHandleGetRowId($xeTable);
                    const handleCell = (item) => {
                        const rowid = handleGetRowId(item);
                        const rowRest = fullDataRowIdData[rowid];
                        // 新增的数据不需要检测
                        if (!rowRest) {
                            return;
                        }
                        const row = rowRest.row;
                        const oRow = sourceDataRowIdData[rowid];
                        if (!oRow) {
                            return;
                        }
                        for (let i = 0; i < keepFields.length; i++) {
                            const field = keepFields[i];
                            const { result, newValue, oldValue } = eqCellValue(row, oRow, field);
                            if (!result) {
                                const column = fullColumnFieldData[field] ? fullColumnFieldData[field].column : null;
                                cellList.push({ row, rowid, column, field, newValue, oldValue });
                            }
                        }
                    };
                    if (treeConfig) {
                        XEUtils.eachTree(tableFullTreeData, handleCell, treeOpts);
                    }
                    else {
                        tableFullData.forEach(handleCell);
                    }
                }
                return cellList;
            },
            /**
             * 获取表格的可视列,也可以指定索引获取列
             * @param {Number} columnIndex 索引
             */
            getColumns(columnIndex) {
                const { visibleColumn } = internalData;
                return XEUtils.isUndefined(columnIndex) ? visibleColumn.slice(0) : visibleColumn[columnIndex];
            },
            /**
             * 根据列获取列的唯一主键
             */
            getColid(fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                return column ? column.id : null;
            },
            /**
             * 根据列的唯一主键获取列
             * @param {String} colid 列主键
             */
            getColumnById(colid) {
                const { fullColumnIdData } = internalData;
                return colid && fullColumnIdData[colid] ? fullColumnIdData[colid].column : null;
            },
            /**
             * 根据列的字段名获取列
             * @param {String} field 字段名
             */
            getColumnByField(field) {
                const fullColumnFieldData = internalData.fullColumnFieldData;
                return field && fullColumnFieldData[field] ? fullColumnFieldData[field].column : null;
            },
            getParentColumn(fieldOrColumn) {
                const { fullColumnIdData } = internalData;
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                return column && column.parentId && fullColumnIdData[column.parentId] ? fullColumnIdData[column.parentId].column : null;
            },
            /**
             * 获取当前表格的列
             * 收集到的全量列、全量表头列、处理条件之后的全量表头列、当前渲染中的表头列
             */
            getTableColumn() {
                return {
                    collectColumn: internalData.collectColumn.slice(0),
                    fullColumn: internalData.tableFullColumn.slice(0),
                    visibleColumn: internalData.visibleColumn.slice(0),
                    tableColumn: reactData.tableColumn.slice(0)
                };
            },
            /**
             * 移动列到指定列的位置
             * @param fieldOrColumn
             * @param targetFieldOrColumn
             * @param options
             */
            moveColumnTo(fieldOrColumn, targetFieldOrColumn, options) {
                const { fullColumnIdData, visibleColumn } = internalData;
                const { dragToChild, dragPos, isCrossDrag } = Object.assign({}, options);
                const dragCol = handleFieldOrColumn($xeTable, fieldOrColumn);
                let prevDragCol = null;
                const colRest = dragCol ? fullColumnIdData[dragCol.id] : null;
                let defPos = 'left';
                if (XEUtils.isNumber(targetFieldOrColumn)) {
                    if (colRest && targetFieldOrColumn) {
                        let currList = colRest.items;
                        let offsetIndex = colRest._index + targetFieldOrColumn;
                        if (isCrossDrag) {
                            currList = visibleColumn;
                            offsetIndex = colRest._index + targetFieldOrColumn;
                        }
                        if (offsetIndex > 0 && offsetIndex < currList.length - 1) {
                            prevDragCol = currList[offsetIndex];
                        }
                        if (targetFieldOrColumn > 0) {
                            defPos = 'right';
                        }
                    }
                }
                else {
                    prevDragCol = handleFieldOrColumn($xeTable, targetFieldOrColumn);
                    const targetColRest = prevDragCol ? fullColumnIdData[prevDragCol.id] : null;
                    if (colRest && targetColRest) {
                        if (targetColRest._index > colRest._index) {
                            defPos = 'right';
                        }
                    }
                }
                return $xeTable.handleColDragSwapEvent(null, true, dragCol, prevDragCol, dragPos || defPos, dragToChild === true);
            },
            /**
             * 移动行到指定行的位置
             * @param rowidOrRow
             * @param targetRowidOrRow
             * @param options
             */
            moveRowTo(rowidOrRow, targetRowidOrRow, options) {
                const { treeConfig } = props;
                const { fullAllDataRowIdData, afterFullData } = internalData;
                const { dragToChild, dragPos, isCrossDrag } = Object.assign({}, options);
                const treeOpts = computeTreeOpts.value;
                const dragRow = handleRowidOrRow($xeTable, rowidOrRow);
                let prevDragRow = null;
                let defPos = 'top';
                const rowRest = dragRow ? fullAllDataRowIdData[getRowid($xeTable, dragRow)] : null;
                if (XEUtils.isNumber(targetRowidOrRow)) {
                    if (rowRest && targetRowidOrRow) {
                        let currList = afterFullData;
                        let offsetIndex = rowRest._index + targetRowidOrRow;
                        if (treeConfig) {
                            currList = rowRest.items;
                            if (treeOpts.transform) {
                                offsetIndex = rowRest.treeIndex + targetRowidOrRow;
                                if (isCrossDrag) {
                                    currList = afterFullData;
                                    offsetIndex = rowRest._index + targetRowidOrRow;
                                }
                            }
                        }
                        if (offsetIndex >= 0 && offsetIndex <= currList.length - 1) {
                            prevDragRow = currList[offsetIndex];
                        }
                        if (targetRowidOrRow > 0) {
                            defPos = 'bottom';
                        }
                    }
                }
                else {
                    prevDragRow = handleRowidOrRow($xeTable, targetRowidOrRow);
                    const targetRowRest = prevDragRow ? fullAllDataRowIdData[getRowid($xeTable, prevDragRow)] : null;
                    if (rowRest && targetRowRest) {
                        if (targetRowRest._index > rowRest._index) {
                            defPos = 'bottom';
                        }
                    }
                }
                const rest = $xeTable.handleRowDragSwapEvent(null, true, dragRow, prevDragRow, dragPos || defPos, dragToChild === true);
                return rest;
            },
            /**
             * 获取表格的全量列
             */
            getFullColumns() {
                const { collectColumn } = internalData;
                return collectColumn.slice(0);
            },
            /**
             * 获取数据,和 data 的行为一致,也可以指定索引获取数据
             */
            getData(rowIndex) {
                const tableSynchData = props.data || internalData.tableSynchData;
                return XEUtils.isUndefined(rowIndex) ? tableSynchData.slice(0) : tableSynchData[rowIndex];
            },
            /**
             * 用于多选行,获取已选中的数据
             */
            getCheckboxRecords(isFull) {
                const { treeConfig } = props;
                const { updateCheckboxFlag } = reactData;
                const { tableFullData, afterFullData, tableFullTreeData, fullDataRowIdData, afterFullRowMaps, selectCheckboxMaps } = internalData;
                const treeOpts = computeTreeOpts.value;
                const checkboxOpts = computeCheckboxOpts.value;
                const { transform, mapChildrenField } = treeOpts;
                const { checkField } = checkboxOpts;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                let rowList = [];
                if (updateCheckboxFlag) {
                    if (checkField) {
                        if (treeConfig) {
                            // 如果开启 transform 默认就是完整数据
                            const currTableData = isFull ? (transform ? tableFullTreeData : tableFullData) : (transform ? tableFullTreeData : afterFullData);
                            rowList = XEUtils.filterTree(currTableData, row => XEUtils.get(row, checkField), { children: transform ? mapChildrenField : childrenField });
                        }
                        else {
                            const currTableData = isFull ? tableFullData : afterFullData;
                            rowList = currTableData.filter((row) => XEUtils.get(row, checkField));
                        }
                    }
                    else {
                        const currMaps = isFull || (treeConfig && !transform) ? fullDataRowIdData : afterFullRowMaps;
                        XEUtils.each(selectCheckboxMaps, (row, rowid) => {
                            if (currMaps[rowid]) {
                                rowList.push(fullDataRowIdData[rowid].row);
                            }
                        });
                    }
                }
                return rowList;
            },
            /**
             * 只对 tree-config 有效,获取行的子级
             */
            getTreeRowChildren(rowOrRowid) {
                const { treeConfig } = props;
                const { fullAllDataRowIdData } = internalData;
                const treeOpts = computeTreeOpts.value;
                const { transform, mapChildrenField } = treeOpts;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                if (rowOrRowid && treeConfig) {
                    let rowid;
                    if (XEUtils.isString(rowOrRowid)) {
                        rowid = rowOrRowid;
                    }
                    else {
                        rowid = getRowid($xeTable, rowOrRowid);
                    }
                    if (rowid) {
                        const rest = fullAllDataRowIdData[rowid];
                        const row = rest ? rest.row : null;
                        if (row) {
                            return row[transform ? mapChildrenField : childrenField] || [];
                        }
                    }
                }
                return [];
            },
            /**
             * 只对 tree-config 有效,用于树形结构,获取指定行的层级
             */
            getTreeRowLevel(rowOrRowid) {
                const { treeConfig } = props;
                const { fullAllDataRowIdData } = internalData;
                if (rowOrRowid && treeConfig) {
                    let rowid;
                    if (XEUtils.isString(rowOrRowid)) {
                        rowid = rowOrRowid;
                    }
                    else {
                        rowid = getRowid($xeTable, rowOrRowid);
                    }
                    if (rowid) {
                        const rest = fullAllDataRowIdData[rowid];
                        if (rest) {
                            return rest.level;
                        }
                    }
                }
                return -1;
            },
            /**
             * 只对 tree-config 有效,获取行的父级
             */
            getTreeParentRow(rowOrRowid) {
                const { treeConfig } = props;
                const { fullAllDataRowIdData } = internalData;
                if (rowOrRowid && treeConfig) {
                    let rowid;
                    if (XEUtils.isString(rowOrRowid)) {
                        rowid = rowOrRowid;
                    }
                    else {
                        rowid = getRowid($xeTable, rowOrRowid);
                    }
                    if (rowid) {
                        const rest = fullAllDataRowIdData[rowid];
                        if (rest) {
                            return rest.parent;
                        }
                    }
                }
                return null;
            },
            getParentRow(rowOrRowid) {
                warnLog('vxe.error.delFunc', ['getParentRow', 'getTreeParentRow']);
                return $xeTable.getTreeParentRow(rowOrRowid);
            },
            /**
             * 根据行的唯一主键获取行
             * @param {String/Number} rowid 行主键
             */
            getRowById(cellValue) {
                const { fullAllDataRowIdData } = internalData;
                const rowid = XEUtils.eqNull(cellValue) ? '' : encodeURIComponent(cellValue || '');
                return fullAllDataRowIdData[rowid] ? fullAllDataRowIdData[rowid].row : null;
            },
            /**
             * 根据行获取行的唯一主键
             * @param {Row} row 行对象
             */
            getRowid(row) {
                return getRowid($xeTable, row);
            },
            /**
             * 获取处理后的表格数据
             * 如果存在筛选条件,继续处理
             * 如果存在排序,继续处理
             */
            getTableData() {
                const { tableData, footerTableData } = reactData;
                const { tableFullData, afterFullData, tableFullTreeData } = internalData;
                return {
                    fullData: props.treeConfig ? tableFullTreeData.slice(0) : tableFullData.slice(0),
                    visibleData: afterFullData.slice(0),
                    tableData: tableData.slice(0),
                    footerData: footerTableData.slice(0)
                };
            },
            /**
             * 获取表格的全量数据,如果是 tree-config 则返回带层级的树结构
             */
            getFullData() {
                const { treeConfig } = props;
                const { tableFullData, tableFullTreeData } = internalData;
                if (treeConfig) {
                    return tableFullTreeData.slice(0);
                }
                return tableFullData.slice(0);
            },
            /**
             * 设置为固定列
             */
            setColumnFixed(fieldOrColumn, fixed) {
                let status = false;
                const cols = XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : [fieldOrColumn];
                const columnOpts = computeColumnOpts.value;
                const isMaxFixedColumn = computeIsMaxFixedColumn.value;
                for (let i = 0; i < cols.length; i++) {
                    const item = cols[i];
                    const column = handleFieldOrColumn($xeTable, item);
                    const targetColumn = getRootColumn($xeTable, column);
                    if (targetColumn && targetColumn.fixed !== fixed) {
                        // 是否超过最大固定列数量
                        if (!targetColumn.fixed && isMaxFixedColumn) {
                            if (VxeUI.modal) {
                                VxeUI.modal.message({
                                    status: 'error',
                                    content: getI18n('vxe.table.maxFixedCol', [columnOpts.maxFixedSize])
                                });
                            }
                            return nextTick();
                        }
                        XEUtils.eachTree([targetColumn], (column) => {
                            column.fixed = fixed;
                            column.renderFixed = fixed;
                        });
                        $xeTable.saveCustomStore('update:fixed');
                        if (!status) {
                            status = true;
                        }
                    }
                }
                if (status) {
                    return $xeTable.refreshColumn();
                }
                return nextTick();
            },
            /**
             * 取消指定固定列
             */
            clearColumnFixed(fieldOrColumn) {
                let status = false;
                const cols = XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : [fieldOrColumn];
                cols.forEach(item => {
                    const column = handleFieldOrColumn($xeTable, item);
                    const targetColumn = getRootColumn($xeTable, column);
                    if (targetColumn && targetColumn.fixed) {
                        XEUtils.eachTree([targetColumn], (column) => {
                            column.fixed = null;
                            column.renderFixed = null;
                        });
                        $xeTable.saveCustomStore('update:fixed');
                        if (!status) {
                            status = true;
                        }
                    }
                });
                if (status) {
                    return $xeTable.refreshColumn();
                }
                return nextTick();
            },
            /**
             * 隐藏指定列
             */
            hideColumn: handleColumnVisible(false),
            /**
             * 显示指定列
             */
            showColumn: handleColumnVisible(true),
            setColumnWidth(fieldOrColumn, width) {
                const { elemStore } = internalData;
                let status = false;
                const cols = XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : [fieldOrColumn];
                let cWidth = XEUtils.toInteger(width);
                if (isScale(width)) {
                    const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                    const bodyWidth = bodyScrollElem ? bodyScrollElem.clientWidth - 1 : 0;
                    cWidth = Math.floor(cWidth * bodyWidth);
                }
                if (cWidth) {
                    cols.forEach(item => {
                        const column = handleFieldOrColumn($xeTable, item);
                        if (column) {
                            column.resizeWidth = cWidth;
                            if (!status) {
                                status = true;
                            }
                        }
                    });
                    if (status) {
                        return $xeTable.refreshColumn().then(() => {
                            return { status };
                        });
                    }
                }
                return nextTick().then(() => {
                    return { status };
                });
            },
            getColumnWidth(fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (column) {
                    return column.renderWidth;
                }
                return 0;
            },
            /**
             * 手动重置列的显示隐藏、列宽拖动的状态、固定列、排序列;
             * 如果为 true 则重置所有状态
             * 如果已关联工具栏,则会同步更新
             */
            resetColumn(options) {
                warnLog('vxe.error.delFunc', ['resetColumn', 'resetCustom']);
                return $xeTable.resetCustom(options);
            },
            /**
             * 刷新列信息
             * 将固定的列左边、右边分别靠边
             * 如果传 true 则会检查列顺序并排序
             */
            refreshColumn(initSort) {
                if (initSort) {
                    handleUpdateColumn();
                }
                return parseColumns(true).then(() => {
                    return $xeTable.refreshScroll();
                }).then(() => {
                    return handleLazyRecalculate(false, true, true);
                });
            },
            setRowHeightConf(heightConf) {
                const { fullAllDataRowIdData } = internalData;
                let status = false;
                if (heightConf) {
                    XEUtils.each(heightConf, (height, rowid) => {
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            const rHeight = XEUtils.toInteger(height);
                            if (rHeight) {
                                rowRest.resizeHeight = rHeight;
                                if (!status) {
                                    status = true;
                                }
                            }
                        }
                    });
                    if (status) {
                        internalData.isResizeCellHeight = true;
                        reactData.resizeHeightFlag++;
                    }
                }
                return nextTick().then(() => {
                    updateRowOffsetTop();
                    return { status };
                });
            },
            getRowHeightConf(isFull) {
                const { fullAllDataRowIdData, afterFullData } = internalData;
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                const rowOpts = computeRowOpts.value;
                const cellOpts = computeCellOpts.value;
                const defaultRowHeight = computeDefaultRowHeight.value;
                const rest = {};
                afterFullData.forEach(row => {
                    const rowid = handleGetRowId(row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (rowRest) {
                        const resizeHeight = rowRest.resizeHeight;
                        if (resizeHeight || isFull) {
                            const currCellHeight = getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                            rest[rowid] = currCellHeight;
                        }
                    }
                });
                return rest;
            },
            recalcRowHeight(rowOrId) {
                const { fullAllDataRowIdData } = internalData;
                const rows = XEUtils.isArray(rowOrId) ? rowOrId : [rowOrId];
                const el = refElem.value;
                if (el) {
                    const { handleGetRowId } = createHandleGetRowId($xeTable);
                    el.setAttribute('data-calc-row', 'Y');
                    rows.forEach(row => {
                        const rowid = XEUtils.isString(row) || XEUtils.isNumber(row) ? row : handleGetRowId(row);
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            rowRest.resizeHeight = calcCellAutoHeight(rowid, rowRest, el);
                        }
                        el.removeAttribute('data-calc-row');
                    });
                    reactData.calcCellHeightFlag++;
                }
                return nextTick();
            },
            setRowHeight(rowOrId, height) {
                const { fullAllDataRowIdData } = internalData;
                let status = false;
                const rows = XEUtils.isArray(rowOrId) ? rowOrId : [rowOrId];
                let rHeight = XEUtils.toInteger(height);
                if (isScale(height)) {
                    const tableBody = refTableBody.value;
                    const bodyElem = tableBody ? tableBody.$el : null;
                    const bodyHeight = bodyElem ? bodyElem.clientHeight - 1 : 0;
                    rHeight = Math.floor(rHeight * bodyHeight);
                }
                if (rHeight) {
                    const { handleGetRowId } = createHandleGetRowId($xeTable);
                    rows.forEach(row => {
                        const rowid = XEUtils.isString(row) || XEUtils.isNumber(row) ? row : handleGetRowId(row);
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            rowRest.resizeHeight = rHeight;
                            if (!status) {
                                status = true;
                            }
                        }
                    });
                    if (status) {
                        internalData.isResizeCellHeight = true;
                        reactData.resizeHeightFlag++;
                    }
                }
                return nextTick().then(() => {
                    return { status };
                });
            },
            getRowHeight(rowOrId) {
                const { fullAllDataRowIdData } = internalData;
                const rowOpts = computeRowOpts.value;
                const cellOpts = computeCellOpts.value;
                const defaultRowHeight = computeDefaultRowHeight.value;
                const rowid = XEUtils.isString(rowOrId) || XEUtils.isNumber(rowOrId) ? rowOrId : getRowid($xeTable, rowOrId);
                const rowRest = fullAllDataRowIdData[rowid];
                if (rowRest) {
                    return getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                }
                return 0;
            },
            /**
             * 刷新滚动操作,手动同步滚动相关位置(对于某些特殊的操作,比如滚动条错位、固定列不同步)
             */
            refreshScroll() {
                const { elemStore, lastScrollLeft, lastScrollTop } = internalData;
                const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
                const leftScrollElem = getRefElem(elemStore['left-body-scroll']);
                const rightScrollElem = getRefElem(elemStore['right-body-scroll']);
                const xHandleEl = refScrollXHandleElem.value;
                const yHandleEl = refScrollYHandleElem.value;
                return new Promise(resolve => {
                    // 还原滚动条位置
                    if (lastScrollLeft || lastScrollTop) {
                        return restoreScrollLocation($xeTable, lastScrollLeft, lastScrollTop).then(() => {
                            // 存在滚动行为未结束情况
                            setTimeout(resolve, 10);
                        });
                    }
                    internalData.intoRunScroll = true;
                    // 重置
                    setScrollTop(yHandleEl, lastScrollTop);
                    setScrollTop(bodyScrollElem, lastScrollTop);
                    setScrollTop(leftScrollElem, lastScrollTop);
                    setScrollTop(rightScrollElem, lastScrollTop);
                    setScrollLeft(xHandleEl, lastScrollLeft);
                    setScrollLeft(bodyScrollElem, lastScrollLeft);
                    setScrollLeft(headerScrollElem, lastScrollLeft);
                    setScrollLeft(footerScrollElem, lastScrollLeft);
                    // 存在滚动行为未结束情况
                    setTimeout(() => {
                        internalData.intoRunScroll = false;
                        resolve();
                    }, 10);
                });
            },
            /**
             * 重新渲染布局
             * 刷新布局
             */
            recalculate(reFull) {
                const isForce = !!reFull;
                return handleLazyRecalculate(isForce, isForce, isForce);
            },
            openTooltip(target, content) {
                const $commTip = refCommTooltip.value;
                if ($commTip && $commTip.open) {
                    return $commTip.open(target, content);
                }
                return nextTick();
            },
            /**
             * 关闭 tooltip
             */
            closeTooltip() {
                const { tooltipStore } = reactData;
                const $tooltip = refTooltip.value;
                const $commTip = refCommTooltip.value;
                if (tooltipStore.visible) {
                    Object.assign(tooltipStore, {
                        row: null,
                        column: null,
                        content: null,
                        visible: false,
                        type: null,
                        currOpts: {}
                    });
                    if ($tooltip && $tooltip.close) {
                        $tooltip.close();
                    }
                }
                if ($commTip && $commTip.close) {
                    $commTip.close();
                }
                return nextTick();
            },
            /**
             * 判断列头复选框是否被选中
             */
            isAllCheckboxChecked() {
                return reactData.isAllSelected;
            },
            /**
             * 判断列头复选框是否被半选
             */
            isAllCheckboxIndeterminate() {
                return !reactData.isAllSelected && reactData.isIndeterminate;
            },
            /**
             * 获取复选框半选状态的行数据
             */
            getCheckboxIndeterminateRecords(isFull) {
                const { treeConfig } = props;
                const { fullDataRowIdData, treeIndeterminateRowMaps } = internalData;
                if (treeConfig) {
                    const fullRest = [];
                    const defRest = [];
                    XEUtils.each(treeIndeterminateRowMaps, (item, rowid) => {
                        if (item) {
                            fullRest.push(item);
                            if (fullDataRowIdData[rowid]) {
                                defRest.push(item);
                            }
                        }
                    });
                    if (isFull) {
                        return fullRest;
                    }
                    return defRest;
                }
                return [];
            },
            /**
             * 用于多选行,设置行为选中状态,第二个参数为选中与否
             * @param {Array/Row} rows 行数据
             * @param {Boolean} value 是否选中
             */
            setCheckboxRow(rows, checked) {
                if (rows && !XEUtils.isArray(rows)) {
                    rows = [rows];
                }
                return handleCheckedCheckboxRow(rows, checked, true);
            },
            setCheckboxRowByKey(keys, checked) {
                const { fullAllDataRowIdData } = internalData;
                if (!XEUtils.isArray(keys)) {
                    keys = [keys];
                }
                const rows = [];
                keys.forEach((rowKey) => {
                    const rowid = encodeRowid(rowKey);
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (rowRest) {
                        rows.push(rowRest.row);
                    }
                });
                return handleCheckedCheckboxRow(rows, checked, true);
            },
            setCheckboxRowKey(keys, checked) {
                return $xeTable.setCheckboxRowByKey(keys, checked);
            },
            isCheckedByCheckboxRow(row) {
                const { updateCheckboxFlag } = reactData;
                const { selectCheckboxMaps } = internalData;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField } = checkboxOpts;
                if (checkField) {
                    return XEUtils.get(row, checkField);
                }
                return !!updateCheckboxFlag && !!selectCheckboxMaps[getRowid($xeTable, row)];
            },
            isCheckedByCheckboxRowKey(rowKey) {
                const { updateCheckboxFlag } = reactData;
                const { fullAllDataRowIdData, selectCheckboxMaps } = internalData;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField } = checkboxOpts;
                const rowid = encodeRowid(rowKey);
                if (checkField) {
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (rowRest) {
                        return XEUtils.get(rowRest.row, checkField);
                    }
                    return false;
                }
                return !!updateCheckboxFlag && !!selectCheckboxMaps[rowid];
            },
            isIndeterminateByCheckboxRow(row) {
                const { treeIndeterminateRowMaps } = internalData;
                return !!treeIndeterminateRowMaps[getRowid($xeTable, row)] && !$xeTable.isCheckedByCheckboxRow(row);
            },
            isIndeterminateByCheckboxRowKey(rowKey) {
                const { treeIndeterminateRowMaps } = internalData;
                const rowid = encodeRowid(rowKey);
                return !!treeIndeterminateRowMaps[rowid] && !$xeTable.isCheckedByCheckboxRowKey(rowid);
            },
            /**
             * 多选,切换某一行的选中状态
             */
            toggleCheckboxRow(row) {
                const { selectCheckboxMaps } = internalData;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField } = checkboxOpts;
                const checked = checkField ? !XEUtils.get(row, checkField) : !selectCheckboxMaps[getRowid($xeTable, row)];
                $xeTable.handleBatchSelectRows([row], checked, true);
                $xeTable.checkSelectionStatus();
                return nextTick();
            },
            /**
             * 用于多选行,设置所有行的选中状态
             * @param {Boolean} value 是否选中
             */
            setAllCheckboxRow(value) {
                return handleCheckedAllCheckboxRow(value, true);
            },
            /**
             * 获取单选框保留选中的行
             */
            getRadioReserveRecord(isFull) {
                const { treeConfig } = props;
                const { fullDataRowIdData, radioReserveRow, afterFullData } = internalData;
                const radioOpts = computeRadioOpts.value;
                const treeOpts = computeTreeOpts.value;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                if (radioOpts.reserve && radioReserveRow) {
                    const rowid = getRowid($xeTable, radioReserveRow);
                    if (isFull) {
                        if (!fullDataRowIdData[rowid]) {
                            return radioReserveRow;
                        }
                    }
                    else {
                        const rowkey = getRowkey($xeTable);
                        if (treeConfig) {
                            const matchObj = XEUtils.findTree(afterFullData, row => rowid === XEUtils.get(row, rowkey), { children: childrenField });
                            if (matchObj) {
                                return radioReserveRow;
                            }
                        }
                        else {
                            if (!afterFullData.some(row => rowid === XEUtils.get(row, rowkey))) {
                                return radioReserveRow;
                            }
                        }
                    }
                }
                return null;
            },
            clearRadioReserve() {
                internalData.radioReserveRow = null;
                return nextTick();
            },
            /**
             * 获取复选框保留选中的行
             */
            getCheckboxReserveRecords(isFull) {
                const { treeConfig } = props;
                const { afterFullData, fullDataRowIdData, checkboxReserveRowMap } = internalData;
                const checkboxOpts = computeCheckboxOpts.value;
                const treeOpts = computeTreeOpts.value;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const reserveSelection = [];
                if (checkboxOpts.reserve) {
                    const { handleGetRowId } = createHandleGetRowId($xeTable);
                    const afterFullIdMaps = {};
                    if (treeConfig) {
                        XEUtils.eachTree(afterFullData, row => {
                            afterFullIdMaps[handleGetRowId(row)] = 1;
                        }, { children: childrenField });
                    }
                    else {
                        afterFullData.forEach(row => {
                            afterFullIdMaps[handleGetRowId(row)] = 1;
                        });
                    }
                    XEUtils.each(checkboxReserveRowMap, (oldRow, oldRowid) => {
                        if (oldRow) {
                            if (isFull) {
                                if (!fullDataRowIdData[oldRowid]) {
                                    reserveSelection.push(oldRow);
                                }
                            }
                            else {
                                if (!afterFullIdMaps[oldRowid]) {
                                    reserveSelection.push(oldRow);
                                }
                            }
                        }
                    });
                }
                return reserveSelection;
            },
            clearCheckboxReserve() {
                internalData.checkboxReserveRowMap = {};
                return nextTick();
            },
            /**
             * 多选,切换所有行的选中状态
             */
            toggleAllCheckboxRow() {
                handleCheckAllEvent(null, !reactData.isAllSelected);
                return nextTick();
            },
            /**
             * 用于多选行,手动清空用户的选择
             * 清空行为不管是否被禁用还是保留记录,都将彻底清空选中状态
             */
            clearCheckboxRow() {
                const { treeConfig } = props;
                const { tableFullData } = internalData;
                const treeOpts = computeTreeOpts.value;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField, reserve } = checkboxOpts;
                // indeterminateField 仅支持读取
                const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField;
                if (checkField) {
                    const handleClearChecked = (item) => {
                        if (treeConfig && indeterminateField) {
                            XEUtils.set(item, indeterminateField, false);
                        }
                        XEUtils.set(item, checkField, false);
                    };
                    if (treeConfig) {
                        XEUtils.eachTree(tableFullData, handleClearChecked, { children: childrenField });
                    }
                    else {
                        tableFullData.forEach(handleClearChecked);
                    }
                }
                if (reserve) {
                    tableFullData.forEach((row) => handleCheckboxReserveRow(row, false));
                }
                reactData.isAllSelected = false;
                reactData.isIndeterminate = false;
                internalData.selectCheckboxMaps = {};
                internalData.treeIndeterminateRowMaps = {};
                reactData.updateCheckboxFlag++;
                return nextTick();
            },
            /**
             * 用于当前行,设置某一行为高亮状态
             * @param {Row} row 行对象
             */
            setCurrentRow(row) {
                const $xeGanttView = internalData.xeGanttView;
                const rowOpts = computeRowOpts.value;
                const el = refElem.value;
                $xeTable.clearCurrentRow();
                // $xeTable.clearCurrentColumn()
                internalData.currentRow = row;
                if (rowOpts.isCurrent || props.highlightCurrentRow) {
                    if (el) {
                        XEUtils.arrayEach(el.querySelectorAll(`[rowid="${getRowid($xeTable, row)}"]`), elem => addClass(elem, 'row--current'));
                    }
                }
                if ($xeGanttView && $xeGanttView.handleUpdateCurrentRow) {
                    $xeGanttView.handleUpdateCurrentRow(row);
                }
                return nextTick();
            },
            isCheckedByRadioRow(row) {
                const { selectRadioRow } = reactData;
                if (row && selectRadioRow) {
                    return $xeTable.eqRow(selectRadioRow, row);
                }
                return false;
            },
            isCheckedByRadioRowKey(key) {
                const { selectRadioRow } = reactData;
                if (selectRadioRow) {
                    return key === getRowid($xeTable, selectRadioRow);
                }
                return false;
            },
            /**
             * 用于单选行,设置某一行为选中状态
             * @param {Row} row 行对象
             */
            setRadioRow(row) {
                return handleCheckedRadioRow(row, true);
            },
            /**
             * 用于单选行,设置某一行为选中状态
             * @param key 行主键
             */
            setRadioByRowKey(rowKey) {
                const { fullAllDataRowIdData } = internalData;
                const rowid = encodeRowid(rowKey);
                const rowRest = fullAllDataRowIdData[rowid];
                if (rowRest) {
                    return handleCheckedRadioRow(rowRest.row, true);
                }
                return nextTick();
            },
            setRadioRowKey(rowKey) {
                return $xeTable.setRadioByRowKey(rowKey);
            },
            /**
             * 用于当前行,手动清空当前高亮的状态
             */
            clearCurrentRow() {
                const $xeGanttView = internalData.xeGanttView;
                const el = refElem.value;
                internalData.currentRow = null;
                internalData.hoverRow = null;
                if (el) {
                    XEUtils.arrayEach(el.querySelectorAll('.row--current'), elem => removeClass(elem, 'row--current'));
                }
                if ($xeGanttView && $xeGanttView.handleUpdateCurrentRow) {
                    $xeGanttView.handleUpdateCurrentRow();
                }
                return nextTick();
            },
            /**
             * 用于单选行,手动清空用户的选择
             */
            clearRadioRow() {
                reactData.selectRadioRow = null;
                return nextTick();
            },
            /**
             * 用于当前行,获取当前行的数据
             */
            getCurrentRecord(isFull) {
                const { fullDataRowIdData, afterFullRowMaps, currentRow } = internalData;
                const rowOpts = computeRowOpts.value;
                if (rowOpts.isCurrent || props.highlightCurrentRow) {
                    const rowid = getRowid($xeTable, currentRow);
                    if (isFull) {
                        if (fullDataRowIdData[rowid]) {
                            return currentRow;
                        }
                    }
                    else {
                        if (afterFullRowMaps[rowid]) {
                            return currentRow;
                        }
                    }
                }
                return null;
            },
            /**
             * 用于单选行,获取当已选中的数据
             */
            getRadioRecord(isFull) {
                const { fullDataRowIdData, afterFullRowMaps } = internalData;
                const { selectRadioRow } = reactData;
                if (selectRadioRow) {
                    const rowid = getRowid($xeTable, selectRadioRow);
                    if (isFull) {
                        if (fullDataRowIdData[rowid]) {
                            return selectRadioRow;
                        }
                    }
                    else {
                        if (afterFullRowMaps[rowid]) {
                            return selectRadioRow;
                        }
                    }
                }
                return null;
            },
            getCurrentColumn() {
                const columnOpts = computeColumnOpts.value;
                return columnOpts.isCurrent || props.highlightCurrentColumn ? reactData.currentColumn : null;
            },
            /**
             * 用于当前列,设置某列行为高亮状态
             */
            setCurrentColumn(fieldOrColumn) {
                const { mouseConfig } = props;
                const mouseOpts = computeMouseOpts.value;
                const isMouseSelected = mouseConfig && mouseOpts.selected;
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (column) {
                    $xeTable.clearCurrentColumn();
                    reactData.currentColumn = column;
                }
                return nextTick().then(() => {
                    // 更新状选中态
                    if (isMouseSelected) {
                        $xeTable.addCellSelectedClass();
                    }
                });
            },
            /**
             * 用于当前列,手动清空当前高亮的状态
             */
            clearCurrentColumn() {
                reactData.currentColumn = null;
                return nextTick();
            },
            setPendingRow(rows, status) {
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                const { pendingRowMaps } = internalData;
                if (rows && !XEUtils.isArray(rows)) {
                    rows = [rows];
                }
                if (status) {
                    rows.forEach((row) => {
                        const rowid = handleGetRowId(row);
                        if (rowid && !pendingRowMaps[rowid]) {
                            pendingRowMaps[rowid] = row;
                        }
                    });
                }
                else {
                    rows.forEach((row) => {
                        const rowid = handleGetRowId(row);
                        if (rowid && pendingRowMaps[rowid]) {
                            delete pendingRowMaps[rowid];
                        }
                    });
                }
                reactData.pendingRowFlag++;
                return nextTick();
            },
            togglePendingRow(rows) {
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                const { pendingRowMaps } = internalData;
                if (rows && !XEUtils.isArray(rows)) {
                    rows = [rows];
                }
                rows.forEach((row) => {
                    const rowid = handleGetRowId(row);
                    if (rowid) {
                        if (pendingRowMaps[rowid]) {
                            delete pendingRowMaps[rowid];
                        }
                        else {
                            pendingRowMaps[rowid] = row;
                        }
                    }
                });
                reactData.pendingRowFlag++;
                return nextTick();
            },
            hasPendingByRow(row) {
                return $xeTable.isPendingByRow(row);
            },
            isPendingByRow(row) {
                const { pendingRowMaps } = internalData;
                const rowid = getRowid($xeTable, row);
                return !!pendingRowMaps[rowid];
            },
            getPendingRecords() {
                const { fullAllDataRowIdData, pendingRowMaps } = internalData;
                const insertRecords = [];
                XEUtils.each(pendingRowMaps, (row, rowid) => {
                    if (fullAllDataRowIdData[rowid]) {
                        insertRecords.push(row);
                    }
                });
                return insertRecords;
            },
            clearPendingRow() {
                internalData.pendingRowMaps = {};
                reactData.pendingRowFlag++;
                return nextTick();
            },
            sort(sortConfs, sortOrder) {
                const sortOpts = computeSortOpts.value;
                const { multiple, remote, orders } = sortOpts;
                if (sortConfs) {
                    if (XEUtils.isString(sortConfs)) {
                        sortConfs = [
                            { field: sortConfs, order: sortOrder }
                        ];
                    }
                }
                if (!XEUtils.isArray(sortConfs)) {
                    sortConfs = [sortConfs];
                }
                if (sortConfs.length) {
                    if (!multiple) {
                        clearAllSort();
                    }
                    (multiple ? sortConfs : [sortConfs[0]]).forEach((confs, index) => {
                        let { field, order } = confs;
                        let column = field;
                        if (XEUtils.isString(field)) {
                            column = $xeTable.getColumnByField(field);
                        }
                        if (column && column.sortable) {
                            if (orders && orders.indexOf(order) === -1) {
                                order = getNextSortOrder(column);
                            }
                            if (column.order !== order) {
                                column.order = order;
                            }
                            column.sortTime = Date.now() + index;
                        }
                    });
                    // 如果是服务端排序,则跳过本地排序处理
                    if (!remote) {
                        $xeTable.handleTableData(true);
                    }
                    return nextTick().then(() => {
                        updateRowOffsetTop();
                        $xeTable.updateCellAreas();
                        return updateStyle();
                    });
                }
                return nextTick();
            },
            setSort(sortConfs, isUpdate) {
                return handleSortEvent(null, sortConfs, isUpdate);
            },
            setSortByEvent(evnt, sortConfs) {
                return handleSortEvent(evnt, sortConfs, true);
            },
            /**
             * 清空指定列的排序条件
             * 如果为空则清空所有列的排序条件
             * @param {String} fieldOrColumn 列或字段名
             */
            clearSort(fieldOrColumn) {
                const sortOpts = computeSortOpts.value;
                if (fieldOrColumn) {
                    const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                    if (column) {
                        column.order = null;
                    }
                }
                else {
                    clearAllSort();
                }
                if (!sortOpts.remote) {
                    $xeTable.handleTableData(true);
                }
                return nextTick().then(() => {
                    updateRowOffsetTop();
                    return updateStyle();
                });
            },
            clearSortByEvent(evnt, fieldOrColumn) {
                const { tableFullColumn } = internalData;
                const sortOpts = computeSortOpts.value;
                const { multiple } = sortOpts;
                const sortCols = [];
                let column = null;
                if (evnt) {
                    if (fieldOrColumn) {
                        column = handleFieldOrColumn($xeTable, fieldOrColumn);
                        if (column) {
                            column.order = null;
                        }
                    }
                    else {
                        tableFullColumn.forEach((column) => {
                            if (column.order) {
                                column.order = null;
                                sortCols.push(column);
                            }
                        });
                    }
                    if (!sortOpts.remote) {
                        $xeTable.handleTableData(true);
                    }
                    if (!multiple) {
                        column = sortCols[0];
                    }
                    if (column) {
                        $xeTable.handleColumnSortEvent(evnt, column);
                    }
                    if (multiple && sortCols.length) {
                        const params = { $table: $xeTable, $event: evnt, cols: sortCols, sortList: [] };
                        dispatchEvent('clear-all-sort', params, evnt);
                    }
                }
                return nextTick().then(() => {
                    updateRowOffsetTop();
                    return updateStyle();
                });
            },
            isSort(fieldOrColumn) {
                if (fieldOrColumn) {
                    const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                    return column ? column.sortable && !!column.order : false;
                }
                return $xeTable.getSortColumns().length > 0;
            },
            getSortColumns() {
                const sortOpts = computeSortOpts.value;
                const { multiple, chronological } = sortOpts;
                const sortList = [];
                const { tableFullColumn } = internalData;
                tableFullColumn.forEach((column) => {
                    const { field, order } = column;
                    if (column.sortable && order) {
                        sortList.push({ column, field, property: field, order: order, sortTime: column.sortTime });
                    }
                });
                if (multiple && chronological && sortList.length > 1) {
                    return XEUtils.orderBy(sortList, 'sortTime');
                }
                return sortList;
            },
            setFilterByEvent(evnt, fieldOrColumn, options) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (column && column.filters) {
                    column.filters = toFilters(options || [], column.id);
                    return $xeTable.handleColumnConfirmFilter(column, evnt);
                }
                return nextTick();
            },
            /**
             * 关闭筛选
             * @param {Event} evnt 事件
             */
            closeFilter() {
                const { filterStore } = reactData;
                const { column, visible } = filterStore;
                filterStore.isAllSelected = false;
                filterStore.isIndeterminate = false;
                filterStore.visible = false;
                if (visible) {
                    const field = column ? column.field : null;
                    dispatchEvent('filter-visible', {
                        column,
                        property: field,
                        field,
                        filterList: () => $xeTable.getCheckedFilters(),
                        visible: false
                    }, null);
                }
                return nextTick();
            },
            /**
             * 判断指定列是否为筛选状态,如果为空则判断所有列
             * @param {String} fieldOrColumn 字段名
             */
            isActiveFilterByColumn(fieldOrColumn) {
                const column = handleFieldOrColumn($xeTable, fieldOrColumn);
                if (column) {
                    return column.filters && column.filters.some((option) => option.checked);
                }
                return $xeTable.getCheckedFilters().length > 0;
            },
            isFilter(fieldOrColumn) {
                return $xeTable.isActiveFilterByColumn(fieldOrColumn);
            },
            clearFilterByEvent(evnt, fieldOrColumn) {
                const { filterStore } = reactData;
                const { tableFullColumn } = internalData;
                const filterOpts = computeFilterOpts.value;
                const { multiple } = filterOpts;
                const filterCols = [];
                let column = null;
                if (fieldOrColumn) {
                    column = handleFieldOrColumn($xeTable, fieldOrColumn);
                    if (column) {
                        $xeTable.handleClearFilter(column);
                    }
                }
                else {
                    tableFullColumn.forEach(column => {
                        if (column.filters) {
                            filterCols.push(column);
                            $xeTable.handleClearFilter(column);
                        }
                    });
                }
                if (!fieldOrColumn || column !== filterStore.column) {
                    Object.assign(filterStore, {
                        isAllSelected: false,
                        isIndeterminate: false,
                        style: null,
                        options: [],
                        column: null,
                        multiple: false, // 选项是覅多选
                        visible: false
                    });
                }
                if (!filterOpts.remote) {
                    $xeTable.updateData();
                }
                if (!multiple) {
                    column = filterCols[0];
                }
                if (column) {
                    const filterList = () => $xeTable.getCheckedFilters();
                    const values = [];
                    const datas = [];
                    column.filters.forEach((item) => {
                        if (item.checked) {
                            values.push(item.value);
                            datas.push(item.data);
                        }
                    });
                    const params = {
                        $table: $xeTable,
                        $event: evnt,
                        column,
                        field: column.field,
                        property: column.field,
                        values,
                        datas,
                        filters: filterList,
                        filterList
                    };
                    $xeTable.dispatchEvent('filter-change', params, evnt);
                    $xeTable.dispatchEvent('clear-filter', params, evnt);
                }
                if (multiple && filterCols.length) {
                    const params = { $table: $xeTable, $event: evnt, cols: filterCols, filterList: [] };
                    dispatchEvent('clear-all-filter', params, evnt);
                }
                return nextTick();
            },
            /**
             * 判断展开行是否懒加载完成
             * @param {Row} row 行对象
             */
            isRowExpandLoaded(row) {
                const { fullAllDataRowIdData } = internalData;
                const rowRest = fullAllDataRowIdData[getRowid($xeTable, row)];
                return rowRest && !!rowRest.expandLoaded;
            },
            clearRowExpandLoaded(row) {
                const { fullAllDataRowIdData, rowExpandLazyLoadedMaps } = internalData;
                const expandOpts = computeExpandOpts.value;
                const { lazy } = expandOpts;
                const rowid = getRowid($xeTable, row);
                const rowRest = fullAllDataRowIdData[rowid];
                if (lazy && rowRest) {
                    rowRest.expandLoaded = false;
                    delete rowExpandLazyLoadedMaps[rowid];
                }
                reactData.rowExpandedFlag++;
                return nextTick();
            },
            /**
             * 重新懒加载展开行,并展开内容
             * @param {Row} row 行对象
             */
            reloadRowExpand(row) {
                const { rowExpandLazyLoadedMaps } = internalData;
                const expandOpts = computeExpandOpts.value;
                const { lazy } = expandOpts;
                const rowid = getRowid($xeTable, row);
                if (lazy && !rowExpandLazyLoadedMaps[rowid]) {
                    $xeTable.clearRowExpandLoaded(row)
                        .then(() => handleAsyncRowExpand(row));
                }
                return nextTick();
            },
            reloadExpandContent(row) {
                warnLog('vxe.error.delFunc', ['reloadExpandContent', 'reloadRowExpand']);
                // 即将废弃
                return $xeTable.reloadRowExpand(row);
            },
            /**
             * 切换展开行
             */
            toggleRowExpand(row) {
                return $xeTable.setRowExpand(row, !$xeTable.isRowExpandByRow(row));
            },
            /**
             * 设置所有行的展开与否
             * @param {Boolean} expanded 是否展开
             */
            setAllRowExpand(expanded) {
                const treeOpts = computeTreeOpts.value;
                const { tableFullData, tableFullTreeData } = internalData;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                let expandedRows = [];
                if (props.treeConfig) {
                    XEUtils.eachTree(tableFullTreeData, (row) => {
                        expandedRows.push(row);
                    }, { children: childrenField });
                }
                else {
                    expandedRows = tableFullData;
                }
                return $xeTable.setRowExpand(expandedRows, expanded);
            },
            /**
             * 设置展开行,二个参数设置这一行展开与否
             * 支持单行
             * 支持多行
             * @param {Array/Row} rows 行数据
             * @param {Boolean} expanded 是否展开
             */
            setRowExpand(rows, expanded) {
                const { expandColumn } = reactData;
                let { fullAllDataRowIdData, rowExpandedMaps, rowExpandLazyLoadedMaps } = internalData;
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                const expandOpts = computeExpandOpts.value;
                const { reserve, lazy, accordion, toggleMethod } = expandOpts;
                const lazyRests = [];
                const columnIndex = expandColumn ? $xeTable.getColumnIndex(expandColumn) : -1;
                const $columnIndex = expandColumn ? $xeTable.getVMColumnIndex(expandColumn) : -1;
                if (rows) {
                    if (!XEUtils.isArray(rows)) {
                        rows = [rows];
                    }
                    if (accordion) {
                        // 只能同时展开一个
                        rowExpandedMaps = {};
                        internalData.rowExpandedMaps = rowExpandedMaps;
                        rows = rows.slice(rows.length - 1, rows.length);
                    }
                    const validRows = toggleMethod ? rows.filter((row) => toggleMethod({ $table: $xeTable, expanded, column: expandColumn, columnIndex, $columnIndex, row, rowIndex: $xeTable.getRowIndex(row), $rowIndex: $xeTable.getVMRowIndex(row) })) : rows;
                    if (expanded) {
                        validRows.forEach((row) => {
                            const rowid = handleGetRowId(row);
                            if (!rowExpandedMaps[rowid]) {
                                const rowRest = fullAllDataRowIdData[rowid];
                                const isLoad = lazy && !rowRest.expandLoaded && !rowExpandLazyLoadedMaps[rowid];
                                if (isLoad) {
                                    lazyRests.push(handleAsyncRowExpand(row));
                                }
                                else {
                                    rowExpandedMaps[rowid] = row;
                                }
                            }
                        });
                    }
                    else {
                        validRows.forEach(item => {
                            const rowid = handleGetRowId(item);
                            if (rowExpandedMaps[rowid]) {
                                delete rowExpandedMaps[rowid];
                            }
                        });
                    }
                    if (reserve) {
                        validRows.forEach((row) => handleRowExpandReserve(row, expanded));
                    }
                }
                reactData.rowExpandedFlag++;
                return Promise.all(lazyRests)
                    .then(() => nextTick())
                    .then(() => handleLazyRecalculate(true, true, true))
                    .then(() => {
                    updateRowOffsetTop();
                    updateRowExpandStyle();
                    handleRowExpandScroll();
                    return $xeTable.updateCellAreas();
                });
            },
            /**
             * 判断行是否为展开状态
             * @param {Row} row 行对象
             */
            isRowExpandByRow(row) {
                const { rowExpandedFlag } = reactData;
                const { rowExpandedMaps } = internalData;
                const rowid = getRowid($xeTable, row);
                return !!rowExpandedFlag && !!rowExpandedMaps[rowid];
            },
            isExpandByRow(row) {
                // 已废弃
                warnLog('vxe.error.delFunc', ['isExpandByRow', 'isRowExpandByRow']);
                return $xeTable.isRowExpandByRow(row);
            },
            /**
             * 手动清空展开行状态,数据会恢复成未展开的状态
             */
            clearRowExpand() {
                const { tableFullData, scrollYStore } = internalData;
                const expandOpts = computeExpandOpts.value;
                const { reserve } = expandOpts;
                const expList = $xeTable.getRowExpandRecords();
                internalData.rowExpandedMaps = {};
                if (reserve) {
                    tableFullData.forEach((row) => handleRowExpandReserve(row, false));
                }
                reactData.rowExpandedFlag++;
                scrollYStore.startIndex = 0;
                scrollYStore.endIndex = 1;
                return nextTick().then(() => {
                    if (expList.length) {
                        return handleLazyRecalculate(true, true, true);
                    }
                }).then(() => {
                    updateRowOffsetTop();
                    updateRowExpandStyle();
                    handleRowExpandScroll();
                    return $xeTable.updateCellAreas();
                });
            },
            clearRowExpandReserve() {
                internalData.rowExpandedReserveRowMap = {};
                return nextTick();
            },
            getRowExpandRecords() {
                const rest = [];
                XEUtils.each(internalData.rowExpandedMaps, item => {
                    if (item) {
                        rest.push(item);
                    }
                });
                return rest;
            },
            setRowGroups(fieldOrColumns) {
                const { aggregateConfig, rowGroupConfig } = props;
                const aggregateOpts = computeAggregateOpts.value;
                const { maxGroupSize } = aggregateOpts;
                if (!(aggregateConfig || rowGroupConfig)) {
                    errLog('vxe.error.reqProp', ['aggregate-config']);
                    return nextTick();
                }
                const confList = fieldOrColumns ? (XEUtils.isArray(fieldOrColumns) ? fieldOrColumns : [fieldOrColumns]) : [];
                if (maxGroupSize && confList.length > maxGroupSize) {
                    if (VxeUI.modal) {
                        VxeUI.modal.message({
                            status: 'error',
                            content: getI18n('vxe.table.maxGroupCol', [maxGroupSize])
                        });
                    }
                    return nextTick();
                }
                if (confList.length) {
                    handleUpdateRowGroup(confList.map(fieldOrColumn => {
                        return XEUtils.isString(fieldOrColumn) ? fieldOrColumn : fieldOrColumn.field;
                    }));
                    return loadTableData(internalData.tableSynchData, false, true);
                }
                return nextTick();
            },
            getRowGroups() {
                const { aggregateConfig, rowGroupConfig } = props;
                const { fullColumnFieldData } = internalData;
                if (aggregateConfig || rowGroupConfig) {
                    const { rowGroupList } = reactData;
                    return rowGroupList.map(({ field }) => {
                        const colRet = fullColumnFieldData[field];
                        if (colRet) {
                            return colRet.column;
                        }
                        return { field };
                    });
                }
                return [];
            },
            getRowGroupFields() {
                return $xeTable.getRowGroups().map(item => item.field);
            },
            clearRowGroups() {
                const { aggregateConfig, rowGroupConfig } = props;
                if (!(aggregateConfig || rowGroupConfig)) {
                    errLog('vxe.error.reqProp', ['aggregate-config']);
                    return nextTick();
                }
                handleUpdateRowGroup([]);
                return loadTableData(internalData.tableSynchData, false, true);
            },
            isRowGroupRecord(row) {
                warnLog('vxe.error.delFunc', ['isRowGroupRecord', 'isAggregateRecord']);
                return $xeTable.isAggregateRecord(row);
            },
            isRowGroupExpandByRow(row) {
                warnLog('vxe.error.delFunc', ['isRowGroupExpandByRow', 'isAggregateExpandByRow']);
                return $xeTable.isAggregateExpandByRow(row);
            },
            isAggregateRecord(row) {
                const { isRowGroupStatus } = reactData;
                return isRowGroupStatus && row.isAggregate;
            },
            getAggregateContentByRow(row) {
                const { isRowGroupStatus } = reactData;
                return isRowGroupStatus && row && row.isAggregate ? row.groupContent : '';
            },
            getAggregateRowChildren(row) {
                const aggregateOpts = computeAggregateOpts.value;
                const { childrenField, mapChildrenField } = aggregateOpts;
                const { isRowGroupStatus } = reactData;
                return isRowGroupStatus && row && row.isAggregate && childrenField && mapChildrenField ? (row[mapChildrenField] || []) : [];
            },
            refreshAggregateCalcValues() {
                updateGroupData();
                return nextTick();
            },
            isAggregateExpandByRow(row) {
                const { rowGroupExpandedFlag } = reactData;
                const { rowGroupExpandedMaps } = internalData;
                return !!rowGroupExpandedFlag && !!rowGroupExpandedMaps[getRowid($xeTable, row)];
            },
            setRowGroupExpand(rows, expanded) {
                if (rows) {
                    if (!XEUtils.isArray(rows)) {
                        rows = [rows];
                    }
                    return handleRowGroupVirtualExpand(rows, expanded);
                }
                return nextTick();
            },
            setRowGroupExpandByField(groupFields, expanded) {
                const { isRowGroupStatus } = reactData;
                const aggregateOpts = computeAggregateOpts.value;
                const { childrenField } = aggregateOpts;
                if (groupFields) {
                    if (!XEUtils.isArray(groupFields)) {
                        groupFields = [groupFields];
                    }
                    if (isRowGroupStatus) {
                        const rows = [];
                        const gfKeys = {};
                        groupFields.forEach(groupField => {
                            gfKeys[groupField] = true;
                        });
                        XEUtils.eachTree(internalData.afterGroupFullData, (row) => {
                            if (row.isAggregate && gfKeys[row.groupField]) {
                                rows.push(row);
                            }
                        }, { children: childrenField });
                        if (rows.length) {
                            return handleRowGroupVirtualExpand(rows, expanded);
                        }
                    }
                }
                return nextTick();
            },
            setAllRowGroupExpand(expanded) {
                const { tableFullGroupData } = internalData;
                const aggregateOpts = computeAggregateOpts.value;
                const { mapChildrenField } = aggregateOpts;
                const rgExpandedMaps = {};
                if (expanded && mapChildrenField) {
                    XEUtils.eachTree(tableFullGroupData, (row) => {
                        if (row[mapChildrenField] && row[mapChildrenField].length) {
                            rgExpandedMaps[getRowid($xeTable, row)] = row;
                        }
                    }, { children: mapChildrenField });
                }
                internalData.rowGroupExpandedMaps = rgExpandedMaps;
                handleVirtualTreeToList();
                $xeTable.handleTableData();
                updateAfterDataIndex();
                reactData.rowGroupExpandedFlag++;
                return handleLazyRecalculate(true, true, true);
            },
            clearRowGroupExpand() {
                internalData.rowGroupExpandedMaps = {};
                handleVirtualTreeToList();
                $xeTable.handleTableData();
                updateAfterDataIndex();
                reactData.rowGroupExpandedFlag++;
                return handleLazyRecalculate(true, true, true);
            },
            getTreeExpandRecords() {
                const rest = [];
                XEUtils.each(internalData.treeExpandedMaps, item => {
                    if (item) {
                        rest.push(item);
                    }
                });
                return rest;
            },
            /**
             * 判断树节点是否懒加载完成
             * @param {Row} row 行对象
             */
            isTreeExpandLoaded(row) {
                const { fullAllDataRowIdData } = internalData;
                const rowRest = fullAllDataRowIdData[getRowid($xeTable, row)];
                return rowRest && !!rowRest.treeLoaded;
            },
            clearTreeExpandLoaded(rows) {
                const { fullAllDataRowIdData, treeExpandedMaps } = internalData;
                const treeOpts = computeTreeOpts.value;
                const { transform } = treeOpts;
                if (rows) {
                    if (!XEUtils.isArray(rows)) {
                        rows = [rows];
                    }
                    rows.forEach((row) => {
                        const rowid = getRowid($xeTable, row);
                        const rowRest = fullAllDataRowIdData[rowid];
                        if (rowRest) {
                            rowRest.treeLoaded = false;
                            if (treeExpandedMaps[rowid]) {
                                delete treeExpandedMaps[rowid];
                            }
                        }
                    });
                }
                else {
                    XEUtils.each(fullAllDataRowIdData, (rowRest) => {
                        rowRest.treeLoaded = false;
                    });
                    internalData.treeExpandedMaps = {};
                }
                if (transform) {
                    handleVirtualTreeToList();
                    $xeTable.handleTableData();
                }
                reactData.treeExpandedFlag++;
                return nextTick();
            },
            /**
             * 重新懒加载树节点,并展开该节点
             * @param {Row} row 行对象
             */
            reloadTreeExpand(row) {
                const { treeExpandLazyLoadedMaps } = internalData;
                const treeOpts = computeTreeOpts.value;
                const hasChildField = treeOpts.hasChild || treeOpts.hasChildField;
                const { transform, lazy } = treeOpts;
                const rowid = getRowid($xeTable, row);
                if (lazy && row[hasChildField] && !treeExpandLazyLoadedMaps[rowid]) {
                    return $xeTable.clearTreeExpandLoaded(row).then(() => {
                        return handleAsyncTreeExpandChilds(row);
                    }).then(() => {
                        if (transform) {
                            handleVirtualTreeToList();
                            $xeTable.handleTableData();
                        }
                        reactData.treeExpandedFlag++;
                    }).then(() => {
                        return $xeTable.recalculate();
                    });
                }
                return nextTick();
            },
            reloadTreeChilds(row) {
                warnLog('vxe.error.delFunc', ['reloadTreeChilds', 'reloadTreeExpand']);
                // 即将废弃
                return $xeTable.reloadTreeExpand(row);
            },
            /**
             * 切换/展开树节点
             */
            toggleTreeExpand(row) {
                return $xeTable.setTreeExpand(row, !$xeTable.isTreeExpandByRow(row));
            },
            /**
             * 设置所有树节点的展开与否
             * @param {Boolean} expanded 是否展开
             */
            setAllTreeExpand(expanded) {
                const { tableFullTreeData } = internalData;
                const treeOpts = computeTreeOpts.value;
                const { transform, lazy } = treeOpts;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const expandeds = [];
                XEUtils.eachTree(tableFullTreeData, (row) => {
                    const rowChildren = row[childrenField];
                    if (lazy || (rowChildren && rowChildren.length)) {
                        expandeds.push(row);
                    }
                }, { children: childrenField });
                return $xeTable.setTreeExpand(expandeds, expanded).then(() => {
                    if (transform) {
                        handleVirtualTreeToList();
                        reactData.treeExpandedFlag++;
                        return $xeTable.recalculate();
                    }
                });
            },
            /**
             * 设置展开树形节点,二个参数设置这一行展开与否
             * 支持单行
             * 支持多行
             * @param {Array/Row} rows 行数据
             * @param {Boolean} expanded 是否展开
             */
            setTreeExpand(rows, expanded) {
                const treeOpts = computeTreeOpts.value;
                const { transform } = treeOpts;
                if (rows) {
                    if (!XEUtils.isArray(rows)) {
                        rows = [rows];
                    }
                    if (rows.length) {
                        // 如果为虚拟树
                        if (transform) {
                            return handleVirtualTreeExpand(rows, expanded);
                        }
                        else {
                            return handleBaseTreeExpand(rows, expanded);
                        }
                    }
                }
                return nextTick();
            },
            /**
             * 判断行是否为树形节点展开状态
             * @param {Row} row 行对象
             */
            isTreeExpandByRow(row) {
                const { treeExpandedFlag } = reactData;
                const { treeExpandedMaps } = internalData;
                return !!treeExpandedFlag && !!treeExpandedMaps[getRowid($xeTable, row)];
            },
            /**
             * 手动清空树形节点的展开状态,数据会恢复成未展开的状态
             */
            clearTreeExpand() {
                const { tableFullTreeData } = internalData;
                const treeOpts = computeTreeOpts.value;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const { transform, reserve } = treeOpts;
                const expList = $xeTable.getTreeExpandRecords();
                internalData.treeExpandedMaps = {};
                if (reserve) {
                    XEUtils.eachTree(tableFullTreeData, row => handleTreeExpandReserve(row, false), { children: childrenField });
                }
                return $xeTable.handleTableData().then(() => {
                    if (transform) {
                        handleVirtualTreeToList();
                        $xeTable.handleTableData();
                    }
                    reactData.treeExpandedFlag++;
                }).then(() => {
                    updateTreeLineStyle();
                    if (expList.length) {
                        return $xeTable.recalculate();
                    }
                });
            },
            clearTreeExpandReserve() {
                internalData.treeExpandedReserveRowMap = {};
                return nextTick();
            },
            /**
             * 获取表格的滚动状态
             */
            getScroll() {
                return $xeTable.getScrollData();
            },
            /**
             * 获取表格的滚动数据
             */
            getScrollData() {
                const { scrollXLoad, scrollYLoad, scrollbarHeight, scrollbarWidth } = reactData;
                const { elemStore } = internalData;
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const scrollTop = bodyScrollElem ? bodyScrollElem.scrollTop : 0;
                const scrollLeft = bodyScrollElem ? bodyScrollElem.scrollLeft : 0;
                const clientHeight = bodyScrollElem ? bodyScrollElem.clientHeight : 0;
                const clientWidth = bodyScrollElem ? bodyScrollElem.clientWidth : 0;
                const scrollHeight = bodyScrollElem ? bodyScrollElem.scrollHeight : 0;
                const scrollWidth = bodyScrollElem ? bodyScrollElem.scrollWidth : 0;
                const isTop = scrollTop <= 0;
                const isBottom = scrollTop + clientHeight >= scrollHeight;
                const isLeft = scrollLeft <= 0;
                const isRight = scrollLeft + clientWidth >= scrollWidth;
                return {
                    virtualX: scrollXLoad,
                    virtualY: scrollYLoad,
                    isTop,
                    isBottom,
                    isLeft,
                    isRight,
                    scrollbarHeight,
                    scrollbarWidth,
                    scrollTop,
                    scrollLeft,
                    scrollHeight,
                    scrollWidth,
                    clientHeight,
                    clientWidth
                };
            },
            /**
             * 如果有滚动条,则滚动到对应的位置
             */
            scrollTo(scrollLeft, scrollTop) {
                const { elemStore } = internalData;
                const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
                const leftScrollElem = getRefElem(elemStore['left-body-scroll']);
                const rightScrollElem = getRefElem(elemStore['right-body-scroll']);
                const xHandleEl = refScrollXHandleElem.value;
                const yHandleEl = refScrollYHandleElem.value;
                internalData.intoRunScroll = true;
                if (scrollLeft) {
                    if (!XEUtils.isNumber(scrollLeft)) {
                        scrollTop = scrollLeft.top;
                        scrollLeft = scrollLeft.left;
                    }
                }
                if (XEUtils.isNumber(scrollLeft)) {
                    setScrollLeft(xHandleEl, scrollLeft);
                    setScrollLeft(bodyScrollElem, scrollLeft);
                    setScrollLeft(headerScrollElem, scrollLeft);
                    setScrollLeft(footerScrollElem, scrollLeft);
                    if (reactData.scrollXLoad) {
                        loadScrollXData();
                    }
                }
                if (XEUtils.isNumber(scrollTop)) {
                    setScrollTop(yHandleEl, scrollTop);
                    setScrollTop(bodyScrollElem, scrollTop);
                    setScrollTop(leftScrollElem, scrollTop);
                    setScrollTop(rightScrollElem, scrollTop);
                    if (reactData.scrollYLoad) {
                        loadScrollYData();
                    }
                }
                return new Promise(resolve => {
                    setTimeout(() => {
                        nextTick(() => {
                            internalData.intoRunScroll = false;
                            resolve();
                        });
                    }, (reactData.scrollXLoad || reactData.scrollYLoad) ? 30 : 0);
                });
            },
            /**
             * 如果有滚动条,则滚动到对应的行
             */
            scrollToRow(rowOrRowid, fieldOrColumn, options) {
                const { isAllOverflow, scrollYLoad, scrollXLoad } = reactData;
                const { fullAllDataRowIdData, _sToTime } = internalData;
                const rest = [];
                let row;
                if (XEUtils.isString(rowOrRowid) || XEUtils.isNumber(rowOrRowid)) {
                    const rowid = rowOrRowid;
                    const rowRest = rowid ? fullAllDataRowIdData[rowid] : null;
                    if (rowRest) {
                        row = rowRest.row;
                    }
                }
                else {
                    row = rowOrRowid;
                }
                if (row) {
                    if (props.treeConfig) {
                        rest.push($xeTable.scrollToTreeRow(row));
                    }
                    else {
                        rest.push(rowToVisible($xeTable, row));
                    }
                }
                if (fieldOrColumn) {
                    rest.push(handleScrollToRowColumn(fieldOrColumn, row, options));
                }
                if (_sToTime) {
                    clearTimeout(_sToTime);
                }
                return Promise.all(rest).then(() => {
                    if (row) {
                        if (!isAllOverflow && (scrollYLoad || scrollXLoad)) {
                            calcCellHeight();
                            calcCellWidth();
                            // 可视区被渲染后位置被偏移
                            internalData._sToTime = setTimeout(() => {
                                internalData._sToTime = undefined;
                                if (scrollYLoad) {
                                    if (props.treeConfig) {
                                        $xeTable.scrollToTreeRow(row);
                                    }
                                    else {
                                        rowToVisible($xeTable, row);
                                    }
                                }
                                if (scrollXLoad && fieldOrColumn) {
                                    handleScrollToRowColumn(fieldOrColumn, row, options);
                                }
                            }, 350);
                        }
                        return nextTick();
                    }
                });
            },
            /**
             * 如果有滚动条,则滚动到第一行
             */
            scrollToStartRow(fieldOrColumn, options) {
                const { afterFullData } = internalData;
                return $xeTable.scrollToRow(afterFullData[0], fieldOrColumn, options);
            },
            /**
             * 如果有滚动条,则滚动到最后一行
             */
            scrollToEndRow(fieldOrColumn, options) {
                const { afterFullData } = internalData;
                return $xeTable.scrollToRow(afterFullData[afterFullData.length - 1], fieldOrColumn, options);
            },
            /**
             * 如果有滚动条,则滚动到对应的列
             */
            scrollToColumn(fieldOrColumn, options) {
                return handleScrollToRowColumn(fieldOrColumn, null, options);
            },
            /**
             * 如果有滚动条,则滚动到第一列
             */
            scrollToStartColumn(options) {
                const { visibleColumn } = internalData;
                return $xeTable.scrollToColumn(visibleColumn[0], options);
            },
            /**
             * 如果有滚动条,则滚动到最后一列
             */
            scrollToEndColumn(options) {
                const { visibleColumn } = internalData;
                return $xeTable.scrollToColumn(visibleColumn[visibleColumn.length - 1], options);
            },
            /**
             * 手动清除滚动相关信息,还原到初始状态
             */
            clearScroll() {
                const { elemStore, scrollXStore, scrollYStore } = internalData;
                const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
                const leftScrollElem = getRefElem(elemStore['left-body-scroll']);
                const rightScrollElem = getRefElem(elemStore['right-body-scroll']);
                const xHandleEl = refScrollXHandleElem.value;
                const yHandleEl = refScrollYHandleElem.value;
                internalData.intoRunScroll = true;
                setScrollLeft(xHandleEl, 0);
                setScrollLeft(bodyScrollElem, 0);
                setScrollLeft(headerScrollElem, 0);
                setScrollLeft(footerScrollElem, 0);
                setScrollTop(yHandleEl, 0);
                setScrollTop(bodyScrollElem, 0);
                setScrollTop(leftScrollElem, 0);
                setScrollTop(rightScrollElem, 0);
                scrollXStore.startIndex = 0;
                scrollXStore.visibleStartIndex = 0;
                scrollXStore.endIndex = scrollXStore.visibleSize;
                scrollXStore.visibleEndIndex = scrollXStore.visibleSize;
                scrollYStore.startIndex = 0;
                scrollYStore.visibleStartIndex = 0;
                scrollYStore.endIndex = scrollYStore.visibleSize;
                scrollYStore.visibleEndIndex = scrollYStore.visibleSize;
                return nextTick().then(() => {
                    internalData.lastScrollLeft = 0;
                    internalData.lastScrollTop = 0;
                    internalData.intoRunScroll = false;
                });
            },
            /**
             * 更新表尾合计
             */
            updateFooter() {
                const { showFooter, footerData, footerMethod } = props;
                const { visibleColumn, afterFullData } = internalData;
                let footData = [];
                if (showFooter && footerData && footerData.length) {
                    footData = footerData.slice(0);
                }
                else if (showFooter && footerMethod) {
                    footData = visibleColumn.length ? footerMethod({ columns: visibleColumn, data: afterFullData, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt }) : [];
                }
                reactData.footerTableData = footData;
                $xeTable.clearFooterFormatterCache();
                $xeTable.handleUpdateFooterMerge();
                $xeTable.dispatchEvent('footer-data-change', {
                    visibleColumn: internalData.visibleColumn,
                    footData
                }, null);
                return nextTick();
            },
            /**
             * 更新列状态 updateStatus({ row, column }, cellValue)
             * 如果组件值 v-model 发生 change 时,调用改函数用于更新某一列编辑状态
             * 如果单元格配置了校验规则,则会进行校验
             */
            updateStatus(slotParams, cellValue) {
                return nextTick().then(() => {
                    const { editRules } = props;
                    const { isActivated } = internalData;
                    if (isActivated && slotParams && editRules) {
                        return $xeTable.handleCellRuleUpdateStatus('change', slotParams, cellValue);
                    }
                });
            },
            /**
             * 设置合并单元格 [{ row: Row|number, column: ColumnInfo|number, rowspan: number, colspan: number }]
             */
            setMergeCells(merges) {
                if (props.spanMethod) {
                    errLog('vxe.error.errConflicts', ['merge-cells', 'span-method']);
                }
                handleBodyMerge(merges);
                $xeTable.handleUpdateBodyMerge();
                return nextTick().then(() => {
                    const { expandColumn } = reactData;
                    const { mergeBodyList } = internalData;
                    if (expandColumn && mergeBodyList.length) {
                        warnLog('vxe.error.errConflicts', ['type=expand', 'merge-cells | span-method']);
                    }
                    $xeTable.updateCellAreas();
                    return updateStyle();
                });
            },
            /**
             * 移除单元格合并 [{row:Row|number, col:ColumnInfo|number}]
             */
            removeMergeCells(merges) {
                if (props.spanMethod) {
                    errLog('vxe.error.errConflicts', ['merge-cells', 'span-method']);
                }
                const rest = removeBodyMerges(merges);
                $xeTable.handleUpdateBodyMerge();
                return nextTick().then(() => {
                    $xeTable.updateCellAreas();
                    updateStyle();
                    return rest;
                });
            },
            /**
             * 获取所有被合并的单元格
             */
            getMergeCells() {
                return internalData.mergeBodyList.slice(0);
            },
            /**
             * 清除所有单元格合并
             */
            clearMergeCells() {
                internalData.mergeBodyList = [];
                internalData.mergeBodyMaps = {};
                internalData.mergeBodyCellMaps = {};
                internalData.mergeBodyRowMaps = {};
                internalData.mergeBodyColMaps = {};
                reactData.mergeBodyFlag++;
                return nextTick().then(() => {
                    return updateStyle();
                });
            },
            setMergeHeaderCells(merges) {
                handleHeaderMerge(merges);
                $xeTable.handleUpdateHeaderMerge();
                return nextTick().then(() => {
                    return updateStyle();
                });
            },
            /**
             * 移除表头单元格合并 [{row:Row|number, col:ColumnInfo|number}]
             */
            removeMergeHeaderCells(merges) {
                const rest = removeHeaderMerges(merges);
                $xeTable.handleUpdateHeaderMerge();
                return nextTick().then(() => {
                    updateStyle();
                    return rest;
                });
            },
            /**
             * 获取所有被合并的表头单元格
             */
            getMergeHeaderCells() {
                return internalData.mergeHeaderList.slice(0);
            },
            /**
             * 清除所有表头单元格合并
             */
            clearMergeHeaderCells() {
                internalData.mergeHeaderList = [];
                internalData.mergeHeaderMaps = {};
                internalData.mergeHeaderCellMaps = {};
                internalData.mergeHeaderRowMaps = {};
                internalData.mergeBodyColMaps = {};
                reactData.mergeHeadFlag++;
                return nextTick().then(() => {
                    return updateStyle();
                });
            },
            setMergeFooterCells(merges) {
                if (props.footerSpanMethod) {
                    errLog('vxe.error.errConflicts', ['merge-footer-cells | merge-footer-items', 'footer-span-method']);
                }
                handleFooterMerge(merges);
                $xeTable.handleUpdateFooterMerge();
                return nextTick().then(() => {
                    return updateStyle();
                });
            },
            setMergeFooterItems(merges) {
                // errLog('vxe.error.delFunc', ['setMergeFooterItems', 'setMergeFooterCells'])
                return $xeTable.setMergeFooterCells(merges);
            },
            removeMergeFooterCells(merges) {
                if (props.footerSpanMethod) {
                    errLog('vxe.error.errConflicts', ['merge-footer-cells | merge-footer-items', 'footer-span-method']);
                }
                const rest = removeFooterMerges(merges);
                $xeTable.handleUpdateFooterMerge();
                return nextTick().then(() => {
                    updateStyle();
                    return rest;
                });
            },
            removeMergeFooterItems(merges) {
                // errLog('vxe.error.delFunc', ['removeMergeFooterItems', 'removeMergeFooterCells'])
                return $xeTable.removeMergeFooterCells(merges);
            },
            /**
             * 获取所有被合并的表尾
             */
            getMergeFooterCells() {
                return internalData.mergeFooterList.slice(0);
            },
            getMergeFooterItems() {
                // errLog('vxe.error.delFunc', ['getMergeFooterItems', 'getMergeFooterCells'])
                return $xeTable.getMergeFooterCells();
            },
            /**
             * 清除所有表尾合并
             */
            clearMergeFooterCells() {
                internalData.mergeFooterList = [];
                internalData.mergeFooterMaps = {};
                internalData.mergeFooterCellMaps = {};
                internalData.mergeFooterRowMaps = {};
                internalData.mergeFooterColMaps = {};
                reactData.mergeFootFlag++;
                return nextTick().then(() => {
                    return updateStyle();
                });
            },
            clearMergeFooterItems() {
                // errLog('vxe.error.delFunc', ['clearMergeFooterItems', 'clearMergeFooterCells'])
                return $xeTable.clearMergeFooterCells();
            },
            updateCellAreas() {
                const { mouseConfig } = props;
                const mouseOpts = computeMouseOpts.value;
                if (mouseConfig && mouseOpts.area && $xeTable.handleRecalculateCellAreaEvent) {
                    return $xeTable.handleRecalculateCellAreaEvent();
                }
                return nextTick();
            },
            undo() {
                return $xeTable.handleUndoStackEvent(null);
            },
            redo() {
                return $xeTable.handleRedoStackEvent(null);
            },
            clearHistory() {
                return $xeTable.handleClearStack();
            },
            /**
             * 用于 custom-config,用于手动恢复自定义列设置信息,恢复表格重置为初始状态
             * @param storeData
             * @returns
             */
            setCustomStoreData(storeData) {
                if (!storeData) {
                    return nextTick();
                }
                const customOpts = computeCustomOpts.value;
                const { checkMethod } = customOpts;
                // 重置状态
                clearTableAllStatus($xeTable);
                // 恢复列
                const allCols = [];
                XEUtils.eachTree(internalData.collectColumn, (column) => {
                    column.resizeWidth = 0;
                    column.fixed = column.defaultFixed;
                    column.renderSortNumber = column.sortNumber;
                    column.parentId = column.defaultParentId;
                    if (!checkMethod || checkMethod({ $table: $xeTable, column })) {
                        column.visible = column.defaultVisible;
                    }
                    column.align = column.defaultAlign;
                    column.headerAlign = column.defaultHeaderAlign;
                    column.footerAlign = column.defaultFooterAlign;
                    column.aggFunc = column.defaultAggFunc;
                    column.renderAggFn = column.defaultAggFunc;
                    column.renderResizeWidth = column.renderWidth;
                    allCols.push(column);
                });
                const newCollectCols = XEUtils.toArrayTree(XEUtils.orderBy(allCols, 'renderSortNumber'), { key: 'id', parentKey: 'parentId', children: 'children' });
                internalData.collectColumn = newCollectCols;
                internalData.tableFullColumn = getColumnList(newCollectCols);
                reactData.updateColFlag++;
                reactData.isColLoading = true;
                initColumnHierarchy();
                return Promise.resolve(handleCustomRestore(storeData)).then(() => {
                    return buildColumnInfo();
                }).then(() => {
                    // 恢复数据聚合分组
                    const { isRowGroupStatus, rowGroupList } = reactData;
                    if (isRowGroupStatus && !!$xeTable.handlePivotTableAggData) {
                        const rowGroupFields = computeRowGroupFields.value;
                        if (rowGroupFields ? rowGroupFields.length : rowGroupList.length) {
                            if (rowGroupFields && rowGroupFields.length) {
                                $xeTable.setRowGroups(rowGroupFields);
                            }
                            else {
                                $xeTable.clearRowGroups();
                            }
                        }
                        else {
                            $xeTable.handleUpdateAggData();
                        }
                    }
                });
            },
            /**
             * 用于 custom-config,用于获取自定义列设置信息,用于自定义保持
             * @returns
             */
            getCustomStoreData() {
                const { id } = props;
                const customOpts = computeCustomOpts.value;
                const { isRowGroupStatus, rowGroupList } = reactData;
                const { fullColumnFieldData, collectColumn } = internalData;
                const { storage, checkMethod } = customOpts;
                const { isCustomAlign, isCustomHeaderAlign, isCustomFooterAlign, isCustomResizable, isCustomVisible, isCustomFixed, isCustomSort, isCustomAggGroup, isCustomAggFunc, isCustomPager } = handleCustomStoreConfig($xeTable);
                const alignData = {};
                const headerAlignData = {};
                const footerAlignData = {};
                const resizableData = {};
                const sortData = [];
                const visibleData = {};
                const fixedData = {};
                const aggGroupData = {};
                const aggFuncData = {};
                const storeData = {
                    pagerData: isCustomPager && $xeGGWrapper && $xeGGWrapper.getCustomPagerData ? $xeGGWrapper.getCustomPagerData() : undefined,
                    alignData: undefined,
                    headerAlignData: undefined,
                    footerAlignData: undefined,
                    resizableData: undefined,
                    sortData: undefined,
                    visibleData: undefined,
                    fixedData: undefined,
                    aggGroupData: undefined,
                    aggFuncData: undefined
                };
                if (!id) {
                    if (storage) {
                        errLog('vxe.error.reqProp', ['id']);
                    }
                    return storeData;
                }
                let hasAlign = 0;
                let hasHeaderAlign = 0;
                let hasFooterAlign = 0;
                let hasResizable = 0;
                let hasSort = 0;
                let hasFixed = 0;
                let hasVisible = 0;
                let hasAggFunc = 0;
                const sortMaps = {};
                XEUtils.eachTree(collectColumn, (column, index, items, path, parentColumn) => {
                    const colKey = column.getKey();
                    if (!colKey) {
                        errLog('vxe.error.reqProp', [`${column.getTitle() || column.type || ''} -> column.field=?`]);
                        return;
                    }
                    if (parentColumn) {
                        if (isCustomSort) {
                            const pColKey = parentColumn.getKey();
                            const psObj = sortMaps[pColKey];
                            hasSort = 1;
                            if (psObj) {
                                const sObj = { k: colKey };
                                sortMaps[colKey] = sObj;
                                if (!psObj.c) {
                                    psObj.c = [];
                                }
                                psObj.c.push(sObj);
                            }
                        }
                    }
                    else {
                        if (isCustomSort) {
                            hasSort = 1;
                            const sObj = { k: colKey };
                            sortMaps[colKey] = sObj;
                            sortData.push(sObj);
                        }
                        // 只支持一级
                        if (isCustomFixed && (column.fixed || '') !== (column.defaultFixed || '')) {
                            hasFixed = 1;
                            fixedData[colKey] = column.fixed;
                        }
                    }
                    if (isCustomAlign && column.align) {
                        hasAlign = 1;
                        alignData[colKey] = column.align;
                    }
                    if (isCustomHeaderAlign && column.headerAlign) {
                        hasHeaderAlign = 1;
                        headerAlignData[colKey] = column.headerAlign;
                    }
                    if (isCustomFooterAlign && column.footerAlign) {
                        hasFooterAlign = 1;
                        footerAlignData[colKey] = column.footerAlign;
                    }
                    if (isCustomResizable && column.resizeWidth) {
                        hasResizable = 1;
                        resizableData[colKey] = column.renderWidth;
                    }
                    if (isCustomVisible && (!checkMethod || checkMethod({ $table: $xeTable, column }))) {
                        if (!column.visible && column.defaultVisible) {
                            hasVisible = 1;
                            visibleData[colKey] = false;
                        }
                        else if (column.visible && !column.defaultVisible) {
                            hasVisible = 1;
                            visibleData[colKey] = true;
                        }
                    }
                    if (isCustomAggFunc && (column.aggFunc || '') !== (column.defaultAggFunc || '')) {
                        hasAggFunc = 1;
                        aggFuncData[colKey] = column.aggFunc;
                    }
                });
                if (hasAlign) {
                    storeData.alignData = alignData;
                }
                if (hasHeaderAlign) {
                    storeData.headerAlignData = headerAlignData;
                }
                if (hasFooterAlign) {
                    storeData.footerAlignData = footerAlignData;
                }
                if (hasResizable) {
                    storeData.resizableData = resizableData;
                }
                if (hasSort) {
                    storeData.sortData = sortData;
                }
                if (hasFixed) {
                    storeData.fixedData = fixedData;
                }
                if (hasVisible) {
                    storeData.visibleData = visibleData;
                }
                if (isCustomAggGroup && isRowGroupStatus) {
                    rowGroupList.forEach(aggConf => {
                        const colRest = fullColumnFieldData[aggConf.field];
                        if (colRest) {
                            aggGroupData[colRest.column.getKey()] = true;
                        }
                    });
                    storeData.aggGroupData = aggGroupData;
                }
                if (hasAggFunc) {
                    storeData.aggFuncData = aggFuncData;
                }
                return storeData;
            },
            focus() {
                internalData.isActivated = true;
                return nextTick();
            },
            blur() {
                internalData.isActivated = false;
                return nextTick();
            },
            /**
             * 已废弃,被 connectToolbar 替换
             * @deprecated
             */
            connect($toolbar) {
                return $xeTable.connectToolbar($toolbar);
            },
            /**
             * 连接工具栏
             * @param $toolbar
             */
            connectToolbar($toolbar) {
                if ($toolbar) {
                    $xeToolbar = $toolbar;
                    $xeToolbar.syncUpdate({ collectColumn: internalData.collectColumn, $table: $xeTable });
                }
                else {
                    errLog('vxe.error.barUnableLink');
                }
                return nextTick();
            }
        };
        /**
         * 全局按下事件处理
         */
        const handleGlobalMousedownEvent = (evnt) => {
            const { editStore, ctxMenuStore, customStore } = reactData;
            const { mouseConfig, editRules } = props;
            const el = refElem.value;
            const editOpts = computeEditOpts.value;
            const validOpts = computeValidOpts.value;
            const areaOpts = computeAreaOpts.value;
            const { actived } = editStore;
            const $validTooltip = refValidTooltip.value;
            const tableFilter = refTableFilter.value;
            const tableCustom = refTableCustom.value;
            const tableMenu = refTableMenu.value;
            // 筛选
            if (tableFilter) {
                if (getEventTargetNode(evnt, el, 'vxe-cell--filter').flag) {
                    // 如果点击了筛选按钮
                }
                else if (getEventTargetNode(evnt, tableFilter.getRefMaps().refElem.value).flag) {
                    // 如果点击筛选容器
                }
                else {
                    if (!getEventTargetNode(evnt, document.body, 'vxe-table--ignore-clear').flag) {
                        $xeTable.preventEvent(evnt, 'event.clearFilter', internalData._currFilterParams, $xeTable.closeFilter);
                    }
                }
            }
            // 自定义列
            if (tableCustom) {
                if (customStore.btnEl === evnt.target || getEventTargetNode(evnt, document.body, 'vxe-toolbar-custom-target').flag) {
                    // 如果点击了自定义列按钮
                }
                else if (getEventTargetNode(evnt, tableCustom.getRefMaps().refElem.value).flag) {
                    // 如果点击自定义列容器
                }
                else {
                    if (!getEventTargetNode(evnt, document.body, 'vxe-table--ignore-clear').flag) {
                        if (customStore.visible && $xeTable.closeCustom) {
                            $xeTable.preventEvent(evnt, 'event.clearCustom', {}, () => {
                                $xeTable.closeCustom();
                                $xeTable.dispatchEvent('custom', { type: 'close' }, evnt);
                            });
                        }
                    }
                }
            }
            // 如果已激活了编辑状态
            if (actived.row) {
                if (!(editOpts.autoClear === false)) {
                    // 如果是激活状态,点击了单元格之外
                    const cell = actived.args.cell;
                    if ((!cell || !getEventTargetNode(evnt, cell).flag)) {
                        if ($validTooltip && getEventTargetNode(evnt, $validTooltip.$el).flag) {
                            // 如果是激活状态,且点击了校验提示框
                        }
                        else if (!internalData._lastCallTime || internalData._lastCallTime + 50 < Date.now()) {
                            // 如果是激活状态,点击了单元格之外
                            if (!getEventTargetNode(evnt, document.body, 'vxe-table--ignore-clear').flag) {
                                // 如果手动调用了激活单元格,避免触发源被移除后导致重复关闭
                                $xeTable.preventEvent(evnt, 'event.clearEdit', actived.args, () => {
                                    let isClear;
                                    if (editOpts.mode === 'row') {
                                        const rowTargetNode = getEventTargetNode(evnt, el, 'vxe-body--row');
                                        const rowNodeRest = rowTargetNode.flag ? $xeTable.getRowNode(rowTargetNode.targetElem) : null;
                                        // row 方式,如果点击了不同行
                                        isClear = rowNodeRest ? !$xeTable.eqRow(rowNodeRest.item, actived.args.row) : false;
                                    }
                                    else {
                                        // cell 方式,如果是非编辑列
                                        isClear = !getEventTargetNode(evnt, el, 'col--edit').flag;
                                    }
                                    // 如果点击表头行,则清除激活状态
                                    if (!isClear) {
                                        isClear = getEventTargetNode(evnt, el, 'vxe-header--row').flag;
                                    }
                                    // 如果点击表尾行,则清除激活状态
                                    if (!isClear) {
                                        isClear = getEventTargetNode(evnt, el, 'vxe-footer--row').flag;
                                    }
                                    // 如果固定了高度且点击了行之外的空白处,则清除激活状态
                                    if (!isClear && props.height && !reactData.overflowY) {
                                        const bodyWrapperElem = evnt.target;
                                        if (hasClass(bodyWrapperElem, 'vxe-table--body-wrapper')) {
                                            isClear = evnt.offsetY < bodyWrapperElem.clientHeight;
                                        }
                                    }
                                    if (isClear ||
                                        // 如果点击了当前表格之外
                                        !getEventTargetNode(evnt, el).flag) {
                                        setTimeout(() => {
                                            $xeTable.handleClearEdit(evnt).then(() => {
                                                // 如果存在校验,点击了表格之外则清除
                                                if (!internalData.isActivated && editRules && validOpts.autoClear) {
                                                    reactData.validErrorMaps = {};
                                                }
                                            });
                                        });
                                    }
                                });
                            }
                        }
                    }
                }
            }
            else if (mouseConfig) {
                if (!getEventTargetNode(evnt, el).flag && !($xeGGWrapper && getEventTargetNode(evnt, $xeGGWrapper.getRefMaps().refElem.value).flag) && !(tableMenu && getEventTargetNode(evnt, tableMenu.getRefMaps().refElem.value).flag) && !($xeToolbar && getEventTargetNode(evnt, $xeToolbar.getRefMaps().refElem.value).flag)) {
                    if ($xeTable.clearSelected) {
                        $xeTable.clearSelected();
                    }
                    if (areaOpts.autoClear) {
                        if ($xeTable.getCellAreas) {
                            const cellAreas = $xeTable.getCellAreas();
                            if (cellAreas && cellAreas.length && !getEventTargetNode(evnt, document.body, 'vxe-table--ignore-areas-clear').flag) {
                                $xeTable.preventEvent(evnt, 'event.clearAreas', {}, () => {
                                    $xeTable.clearCellAreas();
                                    $xeTable.clearCopyCellArea();
                                    dispatchEvent('clear-cell-area-selection', { cellAreas }, evnt);
                                });
                            }
                        }
                    }
                }
            }
            // 如果配置了快捷菜单且,点击了其他地方则关闭
            if ($xeTable.closeMenu) {
                if (ctxMenuStore.visible && tableMenu && !getEventTargetNode(evnt, tableMenu.getRefMaps().refElem.value).flag) {
                    $xeTable.closeMenu();
                }
            }
            if (!(actived.row && getEventTargetNode(evnt, document.body, 'vxe-table--ignore-clear').flag)) {
                const isActivated = getEventTargetNode(evnt, $xeGGWrapper ? $xeGGWrapper.getRefMaps().refElem.value : el).flag;
                // 如果存在校验,点击了表格之外则清除
                if (!isActivated && editRules && validOpts.autoClear) {
                    reactData.validErrorMaps = {};
                }
                // 最后激活的表格
                internalData.isActivated = isActivated;
            }
        };
        /**
         * 窗口失焦事件处理
         */
        const handleGlobalBlurEvent = () => {
            $xeTable.closeFilter();
            if ($xeTable.closeMenu) {
                $xeTable.closeMenu();
            }
        };
        const reUpdateCustomStyleEvent = (evnt) => {
            const { customStore } = reactData;
            const customOpts = computeCustomOpts.value;
            const { popupOptions } = customOpts;
            const { transfer } = popupOptions || {};
            if (transfer && customStore.visible) {
                const tableCustom = refTableCustom.value;
                if (tableCustom && $xeTable.handleCustomStyle && !checkTargetElement(evnt.target, [tableCustom.getRefMaps().refElem.value], evnt.currentTarget)) {
                    $xeTable.handleCustomStyle().then(() => {
                        $xeTable.handleCustomStyle();
                    });
                }
            }
        };
        const handleGlobalScrollEvent = (evnt) => {
            reUpdateCustomStyleEvent(evnt);
        };
        /**
         * 全局滚动事件
         */
        const handleGlobalMousewheelEvent = () => {
            $xeTable.closeTooltip();
            if ($xeTable.closeMenu) {
                $xeTable.closeMenu();
            }
        };
        /**
         * 表格键盘事件
         */
        const keydownEvent = (evnt) => {
            const { mouseConfig, keyboardConfig } = props;
            const { filterStore, ctxMenuStore, editStore } = reactData;
            const mouseOpts = computeMouseOpts.value;
            const keyboardOpts = computeKeyboardOpts.value;
            const { actived } = editStore;
            const isEsc = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ESCAPE);
            if (isEsc) {
                $xeTable.preventEvent(evnt, 'event.keydown', null, () => {
                    dispatchEvent('keydown-start', {}, evnt);
                    if (keyboardConfig && mouseConfig && mouseOpts.area && $xeTable.handleKdClAreaEvent) {
                        $xeTable.handleKdClAreaEvent(evnt);
                    }
                    else if (actived.row || filterStore.visible || ctxMenuStore.visible) {
                        evnt.stopPropagation();
                        // 如果按下了 Esc 键,关闭快捷菜单、筛选
                        if ($xeTable.closeMenu) {
                            $xeTable.closeMenu();
                        }
                        $xeTable.closeFilter();
                        if (keyboardConfig && keyboardOpts.isEsc) {
                            // 如果是激活编辑状态,则取消编辑
                            if (actived.row) {
                                const params = actived.args;
                                $xeTable.handleClearEdit(evnt);
                                // 如果配置了选中功能,则为选中状态
                                if (mouseOpts.selected) {
                                    nextTick(() => $xeTable.handleSelected(params, evnt));
                                }
                            }
                        }
                    }
                    dispatchEvent('keydown', {}, evnt);
                    dispatchEvent('keydown-end', {}, evnt);
                });
            }
        };
        const contextMenuEvent = (evnt) => {
            dispatchEvent('context-menu', {}, evnt);
        };
        /**
         * 全局键盘事件
         */
        const handleGlobalKeydownEvent = (evnt) => {
            // 该行为只对当前激活的表格有效
            if (internalData.isActivated) {
                $xeTable.preventEvent(evnt, 'event.keydown', null, () => {
                    const { mouseConfig, keyboardConfig, treeConfig, editConfig, highlightCurrentRow, highlightCurrentColumn } = props;
                    const { ctxMenuStore, editStore } = reactData;
                    const { afterFullData, visibleColumn, currentRow } = internalData;
                    const isContentMenu = computeIsContentMenu.value;
                    const bodyMenu = computeBodyMenu.value;
                    const keyboardOpts = computeKeyboardOpts.value;
                    const mouseOpts = computeMouseOpts.value;
                    const editOpts = computeEditOpts.value;
                    const treeOpts = computeTreeOpts.value;
                    const menuList = computeMenuList.value;
                    const rowOpts = computeRowOpts.value;
                    const columnOpts = computeColumnOpts.value;
                    const { isLastEnterAppendRow, beforeEnterMethod, enterMethod, isLastTabAppendRow, beforeTabMethod, tabMethod } = keyboardOpts;
                    const { selected, actived } = editStore;
                    const childrenField = treeOpts.children || treeOpts.childrenField;
                    const keyCode = evnt.keyCode;
                    const isProcess = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.PROCESS);
                    const isEsc = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ESCAPE);
                    const hasBackspaceKey = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.BACKSPACE);
                    const isTab = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.TAB);
                    const isEnter = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ENTER);
                    const isSpacebar = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.SPACEBAR);
                    const isLeftArrow = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_LEFT);
                    const isUpArrow = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_UP);
                    const isRightArrow = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_RIGHT);
                    const isDwArrow = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_DOWN);
                    const hasDeleteKey = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.DELETE);
                    const isY = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.Y);
                    const isZ = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.Z);
                    const isF2 = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.F2);
                    const isContextMenu = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.CONTEXT_MENU);
                    const isControlKey = hasControlKey(evnt);
                    const hasShiftKey = evnt.shiftKey;
                    const isAltKey = evnt.altKey;
                    const operArrow = isLeftArrow || isUpArrow || isRightArrow || isDwArrow;
                    const operCtxMenu = isContentMenu && ctxMenuStore.visible && (isEnter || isSpacebar || operArrow);
                    const isEditStatus = isEnableConf(editConfig) && actived.column && actived.row;
                    const beforeEditMethod = editOpts.beforeEditMethod || editOpts.activeMethod;
                    const selectRow = selected.row;
                    const selectColumn = selected.column;
                    if (operCtxMenu) {
                        // 如果配置了右键菜单; 支持方向键操作、回车
                        evnt.preventDefault();
                        if (ctxMenuStore.showChild && hasChildrenList(ctxMenuStore.selected)) {
                            $xeTable.moveCtxMenu(evnt, ctxMenuStore, 'selectChild', isLeftArrow, false, ctxMenuStore.selected.children);
                        }
                        else {
                            $xeTable.moveCtxMenu(evnt, ctxMenuStore, 'selected', isRightArrow, true, menuList);
                        }
                    }
                    else if (keyboardConfig && mouseConfig && mouseOpts.area && $xeTable.handleKdClAreaEvent) {
                        $xeTable.handleKdClAreaEvent(evnt);
                    }
                    else if (isEsc) {
                        // 如果按下了 Esc 键,关闭快捷菜单、筛选
                        if ($xeTable.closeMenu) {
                            $xeTable.closeMenu();
                        }
                        $xeTable.closeFilter();
                        if (keyboardConfig && keyboardOpts.isEsc) {
                            // 如果是激活编辑状态,则取消编辑
                            if (actived.row) {
                                const params = actived.args;
                                $xeTable.handleClearEdit(evnt);
                                // 如果配置了选中功能,则为选中状态
                                if (mouseOpts.selected) {
                                    nextTick(() => $xeTable.handleSelected(params, evnt));
                                }
                            }
                        }
                    }
                    else if (isSpacebar && keyboardConfig && keyboardOpts.isChecked && selectRow && selectColumn && (selectColumn.type === 'checkbox' || selectColumn.type === 'radio')) {
                        // 空格键支持选中复选框
                        evnt.preventDefault();
                        if (selectColumn.type === 'checkbox') {
                            $xeTable.handleToggleCheckRowEvent(evnt, selected.args);
                        }
                        else {
                            $xeTable.triggerRadioRowEvent(evnt, selected.args);
                        }
                    }
                    else if (isF2 && isEnableConf(editConfig)) {
                        if (!isEditStatus) {
                            // 如果按下了 F2 键
                            if (selectRow && selectColumn) {
                                evnt.preventDefault();
                                $xeTable.handleEdit(selected.args, evnt);
                            }
                        }
                    }
                    else if (isContextMenu) {
                        // 如果按下上下文键
                        internalData._keyCtx = selectRow && selectColumn && bodyMenu.length;
                        clearTimeout(internalData.keyCtxTimeout);
                        internalData.keyCtxTimeout = setTimeout(() => {
                            internalData._keyCtx = false;
                        }, 1000);
                    }
                    else if (isEnter && !isAltKey && keyboardConfig && keyboardOpts.isEnter && (selectRow || actived.row || (treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow))) {
                        // 退出选中
                        if (isControlKey) {
                            // 如果是激活编辑状态,则取消编辑
                            if (actived.row) {
                                const params = actived.args;
                                $xeTable.handleClearEdit(evnt);
                                // 如果配置了选中功能,则为选中状态
                                if (mouseOpts.selected) {
                                    nextTick(() => {
                                        $xeTable.handleSelected(params, evnt);
                                    });
                                }
                            }
                        }
                        else {
                            // 如果是激活状态,退则出到上一行/下一行
                            if (selectRow || actived.row) {
                                const activeRow = selectRow || actived.row;
                                const activeColumn = selectColumn || actived.column;
                                if (activeColumn) {
                                    const activeParams = selectRow ? selected.args : actived.args;
                                    if (hasShiftKey) {
                                        if (keyboardOpts.enterToTab) {
                                            $xeTable.moveTabSelected(activeParams, hasShiftKey, evnt);
                                        }
                                        else {
                                            $xeTable.moveEnterSelected(activeParams, isLeftArrow, true, isRightArrow, false, evnt);
                                        }
                                    }
                                    else {
                                        const _rowIndex = $xeTable.getVTRowIndex(activeRow);
                                        const _columnIndex = $xeTable.getVTColumnIndex(activeColumn);
                                        if (keyboardOpts.enterToTab) {
                                            const ttrParams = {
                                                row: activeRow,
                                                rowIndex: $xeTable.getRowIndex(activeRow),
                                                $rowIndex: $xeTable.getVMRowIndex(activeRow),
                                                _rowIndex,
                                                column: activeColumn,
                                                columnIndex: $xeTable.getColumnIndex(activeColumn),
                                                $columnIndex: $xeTable.getVMColumnIndex(activeColumn),
                                                _columnIndex,
                                                $table: $xeTable
                                            };
                                            if (!beforeTabMethod || beforeTabMethod(ttrParams) !== false) {
                                                evnt.preventDefault();
                                                // 最后一行按下Tab键,自动追加一行
                                                if (isLastTabAppendRow) {
                                                    const newColumn = visibleColumn[0];
                                                    if (_rowIndex >= afterFullData.length - 1 && _columnIndex >= visibleColumn.length - 1) {
                                                        if (actived.row) {
                                                            $xeTable.handleClearEdit(evnt);
                                                        }
                                                        $xeTable.insertAt({}, -1).then(({ row: newRow }) => {
                                                            $xeTable.scrollToRow(newRow, newColumn);
                                                            $xeTable.handleSelected(Object.assign(Object.assign({}, activeParams), { row: newRow, column: newColumn }), evnt);
                                                        });
                                                        $xeTable.dispatchEvent('tab-append-row', ttrParams, evnt);
                                                        return;
                                                    }
                                                }
                                                if (tabMethod) {
                                                    tabMethod(ttrParams);
                                                }
                                                else {
                                                    $xeTable.moveTabSelected(activeParams, hasShiftKey, evnt);
                                                }
                                            }
                                        }
                                        else {
                                            const etrParams = {
                                                row: activeRow,
                                                rowIndex: $xeTable.getRowIndex(activeRow),
                                                $rowIndex: $xeTable.getVMRowIndex(activeRow),
                                                _rowIndex,
                                                column: activeColumn,
                                                columnIndex: $xeTable.getColumnIndex(activeColumn),
                                                $columnIndex: $xeTable.getVMColumnIndex(activeColumn),
                                                _columnIndex,
                                                $table: $xeTable
                                            };
                                            if (!beforeEnterMethod || beforeEnterMethod(etrParams) !== false) {
                                                evnt.preventDefault();
                                                // 最后一行按下回车键,自动追加一行
                                                if (isLastEnterAppendRow) {
                                                    if (_rowIndex >= afterFullData.length - 1) {
                                                        $xeTable.insertAt({}, -1).then(({ row: newRow }) => {
                                                            $xeTable.scrollToRow(newRow, activeColumn);
                                                            $xeTable.handleSelected(Object.assign(Object.assign({}, activeParams), { row: newRow }), evnt);
                                                        });
                                                        $xeTable.dispatchEvent('enter-append-row', etrParams, evnt);
                                                        return;
                                                    }
                                                }
                                                if (enterMethod) {
                                                    enterMethod(etrParams);
                                                }
                                                else {
                                                    if (actived.row) {
                                                        $xeTable.handleClearEdit(evnt);
                                                    }
                                                    $xeTable.moveEnterSelected(activeParams, isLeftArrow, false, isRightArrow, true, evnt);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            else if (treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow) {
                                // 如果是树形表格当前行回车移动到子节点
                                const childrens = currentRow[childrenField];
                                if (childrens && childrens.length) {
                                    evnt.preventDefault();
                                    const targetRow = childrens[0];
                                    const params = {
                                        $table: $xeTable,
                                        row: targetRow,
                                        rowIndex: $xeTable.getRowIndex(targetRow),
                                        $rowIndex: $xeTable.getVMRowIndex(targetRow)
                                    };
                                    $xeTable.setTreeExpand(currentRow, true)
                                        .then(() => $xeTable.scrollToRow(targetRow))
                                        .then(() => $xeTable.triggerCurrentRowEvent(evnt, params));
                                }
                            }
                        }
                    }
                    else if (operArrow && keyboardConfig && keyboardOpts.isArrow) {
                        if (!isEditStatus) {
                            // 如果按下了方向键
                            if (mouseOpts.selected && selectRow && selectColumn) {
                                $xeTable.moveArrowSelected(selected.args, isLeftArrow, isUpArrow, isRightArrow, isDwArrow, evnt);
                            }
                            else {
                                // 当前行按键上下移动
                                if ((isUpArrow || isDwArrow) && (rowOpts.isCurrent || highlightCurrentRow)) {
                                    $xeTable.moveCurrentRow(isUpArrow, isDwArrow, evnt);
                                }
                                // 当前行按键左右移动
                                if ((isLeftArrow || isRightArrow) && (columnOpts.isCurrent || highlightCurrentColumn)) {
                                    $xeTable.moveCurrentColumn(isLeftArrow, isRightArrow, evnt);
                                }
                            }
                        }
                    }
                    else if (isTab && keyboardConfig && keyboardOpts.isTab) {
                        // 如果按下了 Tab 键切换
                        if (selectRow || actived.row) {
                            const activeRow = selectRow || actived.row;
                            const activeColumn = selectColumn || actived.column;
                            if (activeColumn) {
                                const activeParams = selectRow ? selected.args : actived.args;
                                const _rowIndex = $xeTable.getVTRowIndex(activeRow);
                                const _columnIndex = $xeTable.getVTColumnIndex(activeColumn);
                                const ttrParams = {
                                    row: activeRow,
                                    rowIndex: $xeTable.getRowIndex(activeRow),
                                    $rowIndex: $xeTable.getVMRowIndex(activeRow),
                                    _rowIndex,
                                    column: activeColumn,
                                    columnIndex: $xeTable.getColumnIndex(activeColumn),
                                    $columnIndex: $xeTable.getVMColumnIndex(activeColumn),
                                    _columnIndex,
                                    $table: $xeTable
                                };
                                if (!beforeTabMethod || beforeTabMethod(ttrParams) !== false) {
                                    evnt.preventDefault();
                                    // 最后一行按下Tab键,自动追加一行
                                    if (isLastTabAppendRow) {
                                        const newColumn = visibleColumn[0];
                                        if (_rowIndex >= afterFullData.length - 1 && _columnIndex >= visibleColumn.length - 1) {
                                            if (actived.row) {
                                                $xeTable.handleClearEdit(evnt);
                                            }
                                            $xeTable.insertAt({}, -1).then(({ row: newRow }) => {
                                                $xeTable.scrollToRow(newRow, newColumn);
                                                $xeTable.handleSelected(Object.assign(Object.assign({}, activeParams), { row: newRow, column: newColumn }), evnt);
                                            });
                                            $xeTable.dispatchEvent('tab-append-row', ttrParams, evnt);
                                            return;
                                        }
                                    }
                                    if (tabMethod) {
                                        tabMethod(ttrParams);
                                    }
                                    else {
                                        if (actived.row) {
                                            $xeTable.handleClearEdit(evnt);
                                        }
                                        $xeTable.moveTabSelected(activeParams, hasShiftKey, evnt);
                                    }
                                }
                            }
                        }
                    }
                    else if (keyboardConfig && keyboardOpts.isDel && hasDeleteKey && isEnableConf(editConfig) && (selectRow || selectColumn)) {
                        // 如果是删除键
                        if (!isEditStatus) {
                            const { delMethod } = keyboardOpts;
                            const params = {
                                row: selectRow,
                                rowIndex: $xeTable.getRowIndex(selectRow),
                                column: selectColumn,
                                columnIndex: $xeTable.getColumnIndex(selectColumn),
                                $table: $xeTable,
                                $grid: $xeGrid,
                                $gantt: $xeGantt
                            };
                            // 是否被禁用
                            if (!beforeEditMethod || beforeEditMethod(params)) {
                                if (delMethod) {
                                    delMethod(params);
                                }
                                else {
                                    const selectCellValue = getCellValue(selectRow, selectColumn);
                                    if (selectCellValue !== null) {
                                        $xeTable.handlePushStack();
                                        setCellValue(selectRow, selectColumn, null);
                                    }
                                }
                                // 如果按下 del 键,更新表尾数据
                                $xeTable.updateFooter();
                                dispatchEvent('cell-delete-value', params, evnt);
                            }
                        }
                    }
                    else if (hasBackspaceKey && keyboardConfig && keyboardOpts.isBack && isEnableConf(editConfig) && (selectRow || selectColumn)) {
                        if (!isEditStatus) {
                            const { backMethod } = keyboardOpts;
                            // 如果是删除键
                            if (keyboardOpts.isDel && isEnableConf(editConfig) && (selectRow || selectColumn)) {
                                const params = {
                                    row: selectRow,
                                    rowIndex: $xeTable.getRowIndex(selectRow),
                                    $rowIndex: $xeTable.getVMRowIndex(selectRow),
                                    _rowIndex: $xeTable.getVTRowIndex(selectRow),
                                    column: selectColumn,
                                    columnIndex: $xeTable.getColumnIndex(selectColumn),
                                    $columnIndex: $xeTable.getVMColumnIndex(selectColumn),
                                    _columnIndex: $xeTable.getVTColumnIndex(selectColumn),
                                    $table: $xeTable,
                                    $grid: $xeGrid,
                                    $gantt: $xeGantt
                                };
                                // 是否被禁用
                                if (!beforeEditMethod || beforeEditMethod(params)) {
                                    if (backMethod) {
                                        backMethod(params);
                                    }
                                    else {
                                        $xeTable.handleEdit(params, evnt, {
                                            isClear: true
                                        });
                                    }
                                    dispatchEvent('cell-backspace-value', params, evnt);
                                }
                            }
                        }
                    }
                    else if (hasBackspaceKey && keyboardConfig && treeConfig && keyboardOpts.isBack && (rowOpts.isCurrent || highlightCurrentRow) && currentRow) {
                        // 如果树形表格回退键关闭当前行返回父节点
                        const { parent: parentRow } = XEUtils.findTree(internalData.afterTreeFullData, item => item === currentRow, { children: childrenField });
                        if (parentRow) {
                            evnt.preventDefault();
                            const params = {
                                row: parentRow,
                                rowIndex: $xeTable.getRowIndex(parentRow),
                                $rowIndex: $xeTable.getVMRowIndex(parentRow),
                                $table: $xeTable,
                                $grid: $xeGrid,
                                $gantt: $xeGantt
                            };
                            $xeTable.setTreeExpand(parentRow, false)
                                .then(() => $xeTable.scrollToRow(parentRow))
                                .then(() => $xeTable.triggerCurrentRowEvent(evnt, params));
                        }
                    }
                    else if (keyboardConfig && keyboardOpts.isUndoRedo && isControlKey && (isZ || isY) && !hasEventInputTarget(evnt.target)) {
                        if (evnt.target) {
                            if (isY || (hasShiftKey && isZ)) {
                                // 恢复被撤销的操作:Ctrl + Y 或 Ctrl + Shift + Z
                                evnt.preventDefault();
                                $xeTable.handleRedoStackEvent(evnt);
                            }
                            else if (isZ) {
                                // ‌撤销上一步操作‌:Ctrl + Z
                                evnt.preventDefault();
                                $xeTable.handleUndoStackEvent(evnt);
                            }
                        }
                    }
                    else if (keyboardConfig && isEnableConf(editConfig) && keyboardOpts.isEdit && !isControlKey && (isSpacebar || isProcess || evnt.key === 'Process' || (keyCode >= 48 && keyCode <= 57) || (keyCode >= 65 && keyCode <= 90) || (keyCode >= 96 && keyCode <= 111) || (keyCode >= 186 && keyCode <= 192) || (keyCode >= 219 && keyCode <= 222))) {
                        const { editMode, editMethod } = keyboardOpts;
                        // 启用编辑后,空格键功能将失效
                        // if (isSpacebar) {
                        //   evnt.preventDefault()
                        // }
                        // 如果是按下非功能键之外允许直接编辑
                        if (selectColumn && selectRow && isEnableConf(selectColumn.editRender)) {
                            const beforeEditMethod = editOpts.beforeEditMethod || editOpts.activeMethod;
                            const params = {
                                row: selectRow,
                                rowIndex: $xeTable.getRowIndex(selectRow),
                                $rowIndex: $xeTable.getVMRowIndex(selectRow),
                                _rowIndex: $xeTable.getVTRowIndex(selectRow),
                                column: selectColumn,
                                columnIndex: $xeTable.getColumnIndex(selectColumn),
                                $columnIndex: $xeTable.getVMColumnIndex(selectColumn),
                                _columnIndex: $xeTable.getVTColumnIndex(selectColumn),
                                $table: $xeTable,
                                $grid: $xeGrid,
                                $gantt: $xeGantt
                            };
                            if (!beforeEditMethod || beforeEditMethod(params)) {
                                if (editMethod) {
                                    editMethod(params);
                                }
                                else {
                                    let isClearValue = false;
                                    // 追加方式与覆盖式
                                    if (editMode !== 'insert') {
                                        isClearValue = true;
                                    }
                                    $xeTable.handleEdit(params, evnt, {
                                        isClear: isClearValue
                                    });
                                }
                            }
                        }
                    }
                    dispatchEvent('keydown', {}, evnt);
                });
            }
        };
        const handleGlobalPasteEvent = (evnt) => {
            const { keyboardConfig, mouseConfig } = props;
            const { editStore, filterStore } = reactData;
            const { isActivated } = internalData;
            const mouseOpts = computeMouseOpts.value;
            const keyboardOpts = computeKeyboardOpts.value;
            const { actived } = editStore;
            if (isActivated && !filterStore.visible) {
                if (!(actived.row || actived.column)) {
                    if (keyboardConfig && keyboardOpts.isClip && mouseConfig && mouseOpts.area && $xeTable.handlePeClAreaEvent) {
                        $xeTable.handlePeClAreaEvent(evnt);
                    }
                }
                dispatchEvent('paste', {}, evnt);
            }
        };
        const handleGlobalCopyEvent = (evnt) => {
            const { keyboardConfig, mouseConfig } = props;
            const { editStore, filterStore } = reactData;
            const { isActivated } = internalData;
            const mouseOpts = computeMouseOpts.value;
            const keyboardOpts = computeKeyboardOpts.value;
            const { actived } = editStore;
            if (isActivated && !filterStore.visible) {
                if (!(actived.row || actived.column)) {
                    if (keyboardConfig && keyboardOpts.isClip && mouseConfig && mouseOpts.area && $xeTable.handleCyClAreaEvent) {
                        $xeTable.handleCyClAreaEvent(evnt);
                    }
                }
                dispatchEvent('copy', {}, evnt);
            }
        };
        const handleGlobalCutEvent = (evnt) => {
            const { keyboardConfig, mouseConfig } = props;
            const { editStore, filterStore } = reactData;
            const { isActivated } = internalData;
            const mouseOpts = computeMouseOpts.value;
            const keyboardOpts = computeKeyboardOpts.value;
            const { actived } = editStore;
            if (isActivated && !filterStore.visible) {
                if (!(actived.row || actived.column)) {
                    if (keyboardConfig && keyboardOpts.isClip && mouseConfig && mouseOpts.area && $xeTable.handleCutCellAreaEvent) {
                        $xeTable.handleCutCellAreaEvent(evnt);
                    }
                }
                dispatchEvent('cut', {}, evnt);
            }
        };
        const handleGlobalResizeEvent = () => {
            if ($xeTable.closeMenu) {
                $xeTable.closeMenu();
            }
            const el = refElem.value;
            if (!el || !el.clientWidth) {
                return;
            }
            if (internalData.rsePending) {
                return;
            }
            handleResizeEvent();
        };
        const handleTargetEnterEvent = (isClear) => {
            const $tooltip = refTooltip.value;
            clearTimeout(internalData.tooltipTimeout);
            if (isClear) {
                $xeTable.closeTooltip();
            }
            else {
                if ($tooltip && $tooltip.setActived) {
                    $tooltip.setActived(true);
                }
            }
        };
        const clearCrossTableDragStatus = () => {
            crossTableDragRowObj = null;
            crossTableDragRowInfo.row = null;
        };
        const clearDragStatus = () => {
            const { dragRow, dragCol } = reactData;
            if (dragRow || dragCol) {
                clearColDropOrigin();
                clearRowDropOrigin();
                hideDropTip();
                clearCrossTableDragStatus();
                reactData.dragRow = null;
                reactData.dragCol = null;
            }
        };
        const handleRowDragEndClearStatus = () => {
            clearRowDragData();
            clearCrossTableDragStatus();
            handleRecalculateStyle(false, true, true);
        };
        const handleColDragEndClearStatus = () => {
            clearColDragData();
            clearCrossTableDragStatus();
            handleRecalculateStyle(true, true, true);
        };
        const clearRowDropOrigin = () => {
            const el = refElem.value;
            if (el) {
                const clss = 'row--drag-origin';
                XEUtils.arrayEach(el.querySelectorAll(`.${clss}`), (elem) => {
                    elem.draggable = false;
                    removeClass(elem, clss);
                });
            }
        };
        const updateRowDropOrigin = (row) => {
            const el = refElem.value;
            if (el) {
                const clss = 'row--drag-origin';
                const rowid = getRowid($xeTable, row);
                XEUtils.arrayEach(el.querySelectorAll(`[rowid="${rowid}"]`), (elem) => {
                    addClass(elem, clss);
                });
            }
        };
        const updateRowDropTipContent = (tdEl) => {
            const { dragConfig } = props;
            const { dragRow } = reactData;
            const rowDragOpts = computeRowDragOpts.value;
            const { tooltipMethod } = rowDragOpts;
            const rTooltipMethod = tooltipMethod || (dragConfig ? dragConfig.rowTooltipMethod : null);
            let tipContent = '';
            if (rTooltipMethod) {
                const rtParams = {
                    $table: $xeTable,
                    row: dragRow
                };
                tipContent = `${rTooltipMethod(rtParams) || ''}`;
            }
            else {
                tipContent = getI18n('vxe.table.dragTip', [tdEl.textContent || '']);
            }
            reactData.dragTipText = tipContent;
        };
        const updateColDropOrigin = (column) => {
            const el = refElem.value;
            if (el) {
                const colQuerys = [];
                XEUtils.eachTree([column], item => {
                    colQuerys.push(`[colid="${item.id}"]`);
                });
                const clss = 'col--drag-origin';
                XEUtils.arrayEach(el.querySelectorAll(colQuerys.join(',')), (elem) => {
                    addClass(elem, clss);
                });
            }
        };
        const clearColDropOrigin = () => {
            const el = refElem.value;
            if (el) {
                const clss = 'col--drag-origin';
                XEUtils.arrayEach(el.querySelectorAll(`.${clss}`), (elem) => {
                    elem.draggable = false;
                    removeClass(elem, clss);
                });
            }
        };
        const updateColDropTipContent = (tdEl) => {
            const { dragCol } = reactData;
            const columnDragOpts = computeColumnDragOpts.value;
            const { tooltipMethod } = columnDragOpts;
            let tipContent = '';
            if (tooltipMethod) {
                const dtParams = {
                    $table: $xeTable,
                    column: dragCol
                };
                tipContent = `${tooltipMethod(dtParams) || ''}`;
            }
            else {
                tipContent = getI18n('vxe.table.dragTip', [tdEl.textContent || '']);
            }
            reactData.dragTipText = tipContent;
        };
        const showDropTip = (evnt, trEl, thEl, showLine, dragPos) => {
            let wrapperEl = refElem.value;
            if ($xeGantt && trEl) {
                const { refGanttContainerElem } = $xeGantt.getRefMaps();
                const ganttContainerElem = refGanttContainerElem.value;
                if (ganttContainerElem) {
                    wrapperEl = ganttContainerElem;
                }
            }
            if (!wrapperEl) {
                return;
            }
            const { overflowX, scrollbarWidth, overflowY, scrollbarHeight } = reactData;
            const { prevDragToChild } = internalData;
            const wrapperRect = wrapperEl.getBoundingClientRect();
            const osbWidth = overflowY ? scrollbarWidth : 0;
            const osbHeight = overflowX ? scrollbarHeight : 0;
            const tableWrapperWidth = wrapperEl.clientWidth;
            const tableWrapperHeight = wrapperEl.clientHeight;
            if (trEl) {
                const rdLineEl = refDragRowLineElem.value;
                if (rdLineEl) {
                    if (showLine) {
                        const scrollbarYToLeft = computeScrollbarYToLeft.value;
                        const trRect = trEl.getBoundingClientRect();
                        let trHeight = trEl.clientHeight;
                        const offsetTop = Math.max(1, trRect.y - wrapperRect.y);
                        if (offsetTop + trHeight > tableWrapperHeight - osbHeight) {
                            trHeight = tableWrapperHeight - offsetTop - osbHeight;
                        }
                        rdLineEl.style.display = 'block';
                        rdLineEl.style.left = `${scrollbarYToLeft ? osbWidth : 0}px`;
                        rdLineEl.style.top = `${offsetTop}px`;
                        rdLineEl.style.height = `${trHeight}px`;
                        rdLineEl.style.width = `${tableWrapperWidth - osbWidth}px`;
                        rdLineEl.setAttribute('drag-pos', dragPos);
                        rdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n');
                    }
                    else {
                        rdLineEl.style.display = '';
                    }
                }
            }
            else if (thEl) {
                const cdLineEl = refDragColLineElem.value;
                if (cdLineEl) {
                    if (showLine) {
                        const scrollbarXToTop = computeScrollbarXToTop.value;
                        const leftContainerElem = refLeftContainer.value;
                        const leftContainerWidth = leftContainerElem ? leftContainerElem.clientWidth : 0;
                        const rightContainerElem = refRightContainer.value;
                        const rightContainerWidth = rightContainerElem ? rightContainerElem.clientWidth : 0;
                        const thRect = thEl.getBoundingClientRect();
                        let thWidth = thEl.clientWidth;
                        const offsetTop = Math.max(0, thRect.y - wrapperRect.y);
                        const startX = leftContainerWidth;
                        let offsetLeft = thRect.x - wrapperRect.x;
                        if (offsetLeft < startX) {
                            thWidth -= startX - offsetLeft;
                            offsetLeft = startX;
                        }
                        const endX = tableWrapperWidth - rightContainerWidth - (rightContainerWidth ? 0 : osbWidth);
                        if (offsetLeft + thWidth > endX) {
                            thWidth = endX - offsetLeft;
                        }
                        cdLineEl.style.display = 'block';
                        cdLineEl.style.top = `${offsetTop}px`;
                        cdLineEl.style.left = `${offsetLeft}px`;
                        cdLineEl.style.width = `${thWidth}px`;
                        if (prevDragToChild) {
                            cdLineEl.style.height = `${thRect.height}px`;
                        }
                        else {
                            cdLineEl.style.height = `${tableWrapperHeight - offsetTop - (scrollbarXToTop ? 0 : osbHeight)}px`;
                        }
                        cdLineEl.setAttribute('drag-pos', dragPos);
                        cdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n');
                    }
                    else {
                        cdLineEl.style.display = '';
                    }
                }
            }
            const rdTipEl = refDragTipElem.value;
            if (rdTipEl) {
                rdTipEl.style.display = 'block';
                rdTipEl.style.top = `${Math.min(wrapperEl.clientHeight - wrapperEl.scrollTop - rdTipEl.clientHeight, evnt.clientY - wrapperRect.y)}px`;
                rdTipEl.style.left = `${Math.min(wrapperEl.clientWidth - wrapperEl.scrollLeft - rdTipEl.clientWidth - 16, evnt.clientX - wrapperRect.x)}px`;
                rdTipEl.setAttribute('drag-status', showLine ? (prevDragToChild ? 'sub' : 'normal') : 'disabled');
            }
        };
        const hideDropTip = () => {
            const rdTipEl = refDragTipElem.value;
            const rdLineEl = refDragRowLineElem.value;
            const cdLineEl = refDragColLineElem.value;
            if (rdTipEl) {
                rdTipEl.style.display = '';
            }
            if (rdLineEl) {
                rdLineEl.style.display = '';
            }
            if (cdLineEl) {
                cdLineEl.style.display = '';
            }
        };
        const clearRowDragData = () => {
            let wrapperEl = refElem.value;
            const dtClss = ['.vxe-body--row'];
            if ($xeGantt) {
                const { refGanttContainerElem } = $xeGantt.getRefMaps();
                const ganttContainerElem = refGanttContainerElem.value;
                if (ganttContainerElem) {
                    wrapperEl = ganttContainerElem;
                }
                dtClss.push('.vxe-gantt-view--body-row', '.vxe-gantt-view--chart-row');
            }
            hideDropTip();
            clearRowDropOrigin();
            clearRowAnimate(wrapperEl, dtClss);
            internalData.prevDragToChild = false;
            reactData.dragRow = null;
            reactData.dragCol = null;
        };
        const clearColDragData = () => {
            const el = refElem.value;
            hideDropTip();
            clearColDropOrigin();
            clearColAnimate(el, ['.vxe-table--column']);
            internalData.prevDragToChild = false;
            reactData.dragRow = null;
            reactData.dragCol = null;
        };
        /**
         * 处理显示 tooltip
         * @param {Event} evnt 事件
         * @param {Row} row 行对象
         */
        const handleTooltip = (evnt, tipOpts, type, tdEl, overflowElem, tipElem, params) => {
            const tipOverEl = overflowElem || tdEl;
            if (!tipOverEl) {
                return nextTick();
            }
            params.cell = tdEl;
            const { tooltipStore } = reactData;
            const { column, row } = params;
            const { showAll, contentMethod } = tipOpts;
            const cellText = XEUtils.toString(column.type === 'html' ? tipOverEl.innerText : tipOverEl.textContent).trim();
            const isOver = tipOverEl.scrollWidth > tipOverEl.clientWidth;
            let isShow = false;
            let customContent = null;
            let content = '';
            if (contentMethod) {
                customContent = contentMethod(params);
            }
            // 是否全部展示
            if (showAll) {
                // 如果为 null 默认显示
                if (XEUtils.eqNull(customContent)) {
                    isShow = true;
                    content = cellText;
                }
                else if (customContent !== '' && customContent !== false) {
                    // 如果为 '' | false 则不显示
                    isShow = true;
                    content = '' + customContent;
                }
            }
            else {
                // 如果为 null 使用默认逻辑
                if (XEUtils.eqNull(customContent)) {
                    isShow = isOver;
                    content = cellText;
                }
                else if (customContent !== '' && customContent !== false) {
                    // 如果为 '' | false 则不显示
                    isShow = true;
                    content = customContent;
                }
                else {
                    content = cellText;
                }
            }
            if (isShow && content) {
                const tipContent = formatText(content);
                Object.assign(tooltipStore, {
                    row,
                    column,
                    visible: true,
                    content: tipContent,
                    type,
                    currOpts: tipOpts
                });
                nextTick(() => {
                    const $tooltip = refTooltip.value;
                    if ($tooltip && $tooltip.open) {
                        $tooltip.open(isOver ? tipOverEl : tipElem, tipContent);
                    }
                });
            }
            return nextTick();
        };
        const truncateStackHistory = () => {
            const { stackHistoryStore } = internalData;
            const { undoStacks } = stackHistoryStore;
            const undoRedoHistoryOpts = computeUndoRedoHistoryOpts.value;
            const { stackSize } = undoRedoHistoryOpts;
            if (undoStacks.length > XEUtils.toNumber(stackSize)) {
                undoStacks.shift();
            }
        };
        /**
         * 生成快照数据
         */
        const getSnapshotStackData = () => {
            const { editStore } = reactData;
            const { afterFullData, elemStore, insertRowMaps, removeRowMaps } = internalData;
            const { selected, actived } = editStore;
            const { row: selectRow, column: selectColumn } = selected;
            const { row: editRow, column: editColumn } = actived;
            const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
            const stackObj = {
                selectActiveInfo: selectRow && selectColumn
                    ? {
                        rowid: getRowid($xeTable, selectRow),
                        colid: selectColumn.id
                    }
                    : undefined,
                editActiveInfo: editRow && editColumn
                    ? {
                        rowid: getRowid($xeTable, editRow),
                        colid: editColumn.id
                    }
                    : undefined,
                scrollInfo: {
                    top: bodyScrollElem ? bodyScrollElem.scrollTop : 0,
                    left: bodyScrollElem ? bodyScrollElem.scrollLeft : 0
                },
                insertData: XEUtils.clone(XEUtils.values(insertRowMaps), true),
                removeData: XEUtils.clone(XEUtils.values(removeRowMaps), true),
                visibleData: XEUtils.clone(afterFullData, true),
                visibleTreeData: [],
                visibleColumn: []
            };
            return $xeTable.getCellAreaPushStackObj ? $xeTable.getCellAreaPushStackObj(stackObj) : stackObj;
        };
        /**
         * 刷新栈视图
         */
        const handleUpdateSnapshotStackData = (stackObj) => {
            const { treeConfig } = props;
            const { editStore } = reactData;
            const { fullAllDataRowIdData, fullColumnIdData } = internalData;
            if (!stackObj) {
                return;
            }
            const treeOpts = computeTreeOpts.value;
            const { transform } = treeOpts;
            const { visibleData, editActiveInfo, selectActiveInfo, scrollInfo, insertData, removeData } = stackObj;
            const iRowMaps = {};
            insertData.forEach(item => {
                const rowid = getRowid($xeTable, item);
                const rest = fullAllDataRowIdData[rowid];
                let row = item;
                if (rest) {
                    row = rest.row;
                    Object.assign(row, item);
                }
                iRowMaps[rowid] = row;
            });
            const rRowMaps = {};
            removeData.forEach(item => {
                const rowid = getRowid($xeTable, item);
                const rest = fullAllDataRowIdData[rowid];
                let row = item;
                if (rest) {
                    row = rest.row;
                    Object.assign(row, item);
                }
                rRowMaps[rowid] = row;
            });
            const afterFullList = visibleData.map(item => {
                const rowid = getRowid($xeTable, item);
                const rest = fullAllDataRowIdData[rowid];
                let row = item;
                if (rest) {
                    row = rest.row;
                    Object.assign(row, item);
                }
                return row;
            });
            internalData.insertRowMaps = iRowMaps;
            internalData.removeRowMaps = rRowMaps;
            internalData.afterFullData = afterFullList;
            $xeTable.cacheRowMap(false);
            $xeTable.handleTableData(treeConfig && transform);
            $xeTable.updateFooter();
            $xeTable.handleUpdateBodyMerge();
            if (!(treeConfig && transform)) {
                $xeTable.updateAfterDataIndex();
            }
            $xeTable.checkSelectionStatus();
            if (reactData.scrollYLoad) {
                $xeTable.updateScrollYSpace();
            }
            if ($xeTable.handleCellAreaSnapshotStackData) {
                $xeTable.handleCellAreaSnapshotStackData(stackObj);
            }
            else {
                const { selected } = editStore;
                const mouseOpts = computeMouseOpts.value;
                let selectRowid = '';
                let selectColid = '';
                if (editActiveInfo) {
                    selectRowid = editActiveInfo.rowid;
                    selectColid = editActiveInfo.colid;
                }
                else if (selectActiveInfo) {
                    selectRowid = selectActiveInfo.rowid;
                    selectColid = selectActiveInfo.colid;
                }
                if (selectRowid && selectColid && mouseOpts.selected) {
                    const editRow = fullAllDataRowIdData[selectRowid] ? fullAllDataRowIdData[selectRowid].row : null;
                    const editColumn = fullColumnIdData[selectColid] ? fullColumnIdData[selectColid].column : null;
                    if (editRow && editColumn) {
                        const params = {
                            row: editRow,
                            column: editColumn
                        };
                        selected.row = editRow;
                        selected.column = editColumn;
                        selected.args = params;
                        nextTick(() => {
                            $xeTable.addCellSelectedClass();
                            $xeTable.scrollTo(scrollInfo);
                        });
                    }
                }
            }
        };
        const callSlot = (slotFunc, params) => {
            if (slotFunc) {
                if ($xeGGWrapper) {
                    return $xeGGWrapper.callSlot(slotFunc, params);
                }
                // if (XEUtils.isString(slotFunc)) {
                //   slotFunc = slots[slotFunc] || null
                // }
                if (XEUtils.isFunction(slotFunc)) {
                    return getSlotVNs(slotFunc(params));
                }
            }
            return [];
        };
        /**
         * 内部方法
         */
        tablePrivateMethods = {
            getSetupOptions() {
                return getConfig();
            },
            updateAfterDataIndex,
            callSlot,
            /**
             * 获取父容器元素
             */
            getParentElem() {
                const el = refElem.value;
                if ($xeGGWrapper) {
                    const gridEl = $xeGGWrapper.getRefMaps().refElem.value;
                    return gridEl ? gridEl.parentNode : null;
                }
                return el ? el.parentNode : null;
            },
            /**
             * 获取父容器的高度
             */
            getParentHeight() {
                const { height } = props;
                const el = refElem.value;
                if (el) {
                    const parentElem = el.parentNode;
                    let parentPaddingSize = 0;
                    let parentWrapperHeight = 0;
                    if (parentElem) {
                        if ($xeGantt && hasClass(parentElem, 'vxe-gantt--table-wrapper')) {
                            parentWrapperHeight = $xeGantt.getParentHeight();
                        }
                        else if ($xeGrid && hasClass(parentElem, 'vxe-grid--table-wrapper')) {
                            parentWrapperHeight = $xeGrid.getParentHeight();
                        }
                        else {
                            parentWrapperHeight = parentElem.clientHeight;
                            parentPaddingSize = height === '100%' || height === 'auto' ? getPaddingTopBottomSize(parentElem) : 0;
                        }
                    }
                    return Math.floor(parentWrapperHeight - parentPaddingSize);
                }
                return 0;
            },
            /**
             * 获取需要排除的高度
             * 但渲染表格高度时,需要排除工具栏或分页等相关组件的高度
             * 如果存在表尾合计滚动条,则需要排除滚动条高度
             */
            getExcludeHeight() {
                return $xeGGWrapper ? $xeGGWrapper.getExcludeHeight() : 0;
            },
            /**
             * 定义行数据中的列属性,如果不存在则定义
             * @param {Row} records 行数据
             */
            defineField(records) {
                const { treeConfig } = props;
                const expandOpts = computeExpandOpts.value;
                const treeOpts = computeTreeOpts.value;
                const radioOpts = computeRadioOpts.value;
                const rowOpts = computeRowOpts.value;
                const checkboxOpts = computeCheckboxOpts.value;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const rowkey = getRowkey($xeTable);
                if (!XEUtils.isArray(records)) {
                    records = [records];
                }
                return records.map(record => {
                    internalData.tableFullColumn.forEach(column => {
                        const { field, editRender } = column;
                        if (field && !XEUtils.has(record, field) && !record[field]) {
                            let cellValue = null;
                            if (editRender) {
                                const { defaultValue } = editRender;
                                if (XEUtils.isFunction(defaultValue)) {
                                    cellValue = defaultValue({ column });
                                }
                                else if (!XEUtils.isUndefined(defaultValue)) {
                                    cellValue = defaultValue;
                                }
                            }
                            XEUtils.set(record, field, cellValue);
                        }
                    });
                    const otherFields = [radioOpts.labelField, checkboxOpts.checkField, checkboxOpts.labelField, expandOpts.labelField];
                    otherFields.forEach((key) => {
                        if (key && eqEmptyValue(XEUtils.get(record, key))) {
                            XEUtils.set(record, key, null);
                        }
                    });
                    if (treeConfig && treeOpts.lazy && XEUtils.isUndefined(record[childrenField])) {
                        record[childrenField] = null;
                    }
                    // 必须有行数据的唯一主键,可以自行设置;也可以默认生成一个随机数
                    if (eqEmptyValue(XEUtils.get(record, rowkey))) {
                        XEUtils.set(record, rowkey, createRowId(rowOpts, record, rowkey));
                    }
                    return record;
                });
            },
            handleTableData(force) {
                const { scrollYLoad } = reactData;
                const { scrollYStore, fullDataRowIdData } = internalData;
                const $xeGanttView = internalData.xeGanttView;
                let fullList = internalData.afterFullData;
                // 是否进行数据处理
                if (force) {
                    // 更新数据,处理筛选和排序
                    updateAfterFullData();
                    // 如果为虚拟树,将树结构拍平
                    fullList = handleVirtualTreeToList();
                    // 更新数据后清除合并缓存,涉及分组、筛选、排序等
                    internalData.mergeHeaderRowMaps = {};
                    internalData.mergeHeaderColMaps = {};
                    internalData.mergeBodyRowMaps = {};
                    internalData.mergeBodyColMaps = {};
                    internalData.mergeFooterRowMaps = {};
                    internalData.mergeFooterColMaps = {};
                }
                const tableData = scrollYLoad ? fullList.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullList.slice(0);
                const visibleDataRowIdMaps = {};
                tableData.forEach((row, $index) => {
                    const rowid = getRowid($xeTable, row);
                    const rest = fullDataRowIdData[rowid];
                    if (rest) {
                        rest.$index = $index;
                    }
                    visibleDataRowIdMaps[rowid] = row;
                });
                reactData.tableData = tableData;
                internalData.visibleDataRowIdData = visibleDataRowIdMaps;
                if ($xeGanttView && $xeGanttView.updateViewData) {
                    $xeGanttView.updateViewData(force);
                }
                return nextTick();
            },
            /**
             * 更新数据行的 Map
             */
            cacheRowMap(isReset) {
                const { treeConfig } = props;
                const { isRowGroupStatus } = reactData;
                const { currKeyField, fullAllDataRowIdData, tableFullData, tableFullTreeData, tableFullGroupData, treeExpandedMaps, rowExpandedMaps, selectCheckboxMaps } = internalData;
                const fullAllDataRowIdMaps = isReset ? {} : Object.assign({}, fullAllDataRowIdData); // 存在已删除数据
                const fullDataRowIdMaps = {};
                const idMaps = {};
                const { handleUpdateRowId } = createHandleUpdateRowId($xeTable);
                let rowNum = 0;
                const handleRowCache = (row, index, items, currIndex, parentRow, rowid, level, seq) => {
                    let rowRest = fullAllDataRowIdMaps[rowid];
                    if (idMaps[rowid]) {
                        errLog('vxe.error.repeatKey', [currKeyField, rowid]);
                    }
                    if (!rowRest) {
                        rowRest = { row, rowid, _seq: -1, seq, index: -1, _index: -1, $index: -1, treeIndex: index, _tIndex: -1, items, parent: parentRow, level, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 };
                        fullDataRowIdMaps[rowid] = rowRest;
                        fullAllDataRowIdMaps[rowid] = rowRest;
                    }
                    rowRest.treeLoaded = false;
                    rowRest.expandLoaded = false;
                    rowRest._seq = rowNum++;
                    rowRest.row = row;
                    rowRest.items = items;
                    rowRest.parent = parentRow;
                    rowRest.level = level;
                    rowRest.index = currIndex;
                    rowRest.treeIndex = index;
                    // 更新缓存
                    if (selectCheckboxMaps[rowid]) {
                        selectCheckboxMaps[rowid] = row;
                    }
                    if (rowExpandedMaps[rowid]) {
                        rowExpandedMaps[rowid] = row;
                    }
                    rowNum++;
                    idMaps[rowid] = true;
                    fullDataRowIdMaps[rowid] = rowRest;
                    fullAllDataRowIdMaps[rowid] = rowRest;
                };
                if (treeConfig) {
                    const treeOpts = computeTreeOpts.value;
                    const { lazy } = treeOpts;
                    const childrenField = treeOpts.children || treeOpts.childrenField;
                    const hasChildField = treeOpts.hasChild || treeOpts.hasChildField;
                    XEUtils.eachTree(tableFullTreeData, (row, index, items, path, parentRow, nodes) => {
                        const rowid = handleUpdateRowId(row);
                        if (lazy) {
                            if (row[hasChildField] && row[childrenField] === undefined) {
                                row[childrenField] = null;
                            }
                            if (treeExpandedMaps[rowid]) {
                                if (!row[childrenField] || !row[childrenField].length) {
                                    delete treeExpandedMaps[rowid];
                                }
                            }
                        }
                        handleRowCache(row, index, items, parentRow ? -1 : index, parentRow, rowid, nodes.length - 1, toTreePathSeq(path));
                    }, { children: childrenField });
                }
                else if (isRowGroupStatus) {
                    const aggregateOpts = computeAggregateOpts.value;
                    const { mapChildrenField } = aggregateOpts;
                    XEUtils.eachTree(tableFullGroupData, (row, index, items, path, parentRow, nodes) => {
                        const rowid = handleUpdateRowId(row);
                        handleRowCache(row, index, items, parentRow ? -1 : index, parentRow, rowid, nodes.length - 1, toTreePathSeq(path));
                    }, { children: mapChildrenField });
                }
                else {
                    tableFullData.forEach((row, index, items) => {
                        handleRowCache(row, index, items, index, null, handleUpdateRowId(row), 0, index + 1);
                    });
                }
                internalData.fullDataRowIdData = fullDataRowIdMaps;
                internalData.fullAllDataRowIdData = fullAllDataRowIdMaps;
                reactData.treeExpandedFlag++;
            },
            cacheSourceMap(fullData) {
                const { treeConfig } = props;
                const treeOpts = computeTreeOpts.value;
                const sourceData = XEUtils.clone(fullData, true);
                const { handleUpdateRowId } = createHandleUpdateRowId($xeTable);
                const sourceRowIdData = {};
                const handleSourceRow = (row) => {
                    const rowid = handleUpdateRowId(row);
                    sourceRowIdData[rowid] = row;
                };
                // 源数据缓存
                if (treeConfig) {
                    const childrenField = treeOpts.children || treeOpts.childrenField;
                    XEUtils.eachTree(sourceData, handleSourceRow, { children: treeOpts.transform ? treeOpts.mapChildrenField : childrenField });
                }
                else {
                    sourceData.forEach(handleSourceRow);
                }
                internalData.sourceDataRowIdData = sourceRowIdData;
                internalData.tableSourceData = sourceData;
            },
            /**
             * 指定列宽的列进行拆分
             */
            analyColumnWidth() {
                const { tableFullColumn } = internalData;
                const columnOpts = computeColumnOpts.value;
                const { width: defaultWidth, minWidth: defaultMinWidth } = columnOpts;
                const resizeList = [];
                const pxList = [];
                const pxMinList = [];
                const autoMinList = [];
                const scaleList = [];
                const scaleMinList = [];
                const autoList = [];
                const remainList = [];
                tableFullColumn.forEach((column) => {
                    if (defaultWidth && !column.width) {
                        column.width = defaultWidth;
                    }
                    if (defaultMinWidth && !column.minWidth) {
                        column.minWidth = defaultMinWidth;
                    }
                    if (column.visible) {
                        if (column.resizeWidth) {
                            resizeList.push(column);
                        }
                        else if (column.width === 'auto') {
                            autoList.push(column);
                        }
                        else if (isPx(column.width)) {
                            pxList.push(column);
                        }
                        else if (isScale(column.width)) {
                            scaleList.push(column);
                        }
                        else if (isPx(column.minWidth)) {
                            pxMinList.push(column);
                        }
                        else if (column.minWidth === 'auto') {
                            autoMinList.push(column);
                        }
                        else if (isScale(column.minWidth)) {
                            scaleMinList.push(column);
                        }
                        else {
                            remainList.push(column);
                        }
                    }
                });
                Object.assign(reactData.columnStore, { resizeList, pxList, pxMinList, autoMinList, scaleList, scaleMinList, autoList, remainList });
            },
            handleColResizeMousedownEvent(evnt, fixedType, params) {
                const isLeftBtn = evnt.button === 0;
                if (!isLeftBtn) {
                    return;
                }
                evnt.stopPropagation();
                evnt.preventDefault();
                const { column } = params;
                const { columnStore, overflowX, scrollbarHeight } = reactData;
                const { visibleColumn } = internalData;
                const { leftList, rightList } = columnStore;
                const resizableOpts = computeResizableOpts.value;
                const osbHeight = overflowX ? scrollbarHeight : 0;
                const tableEl = refElem.value;
                const leftContainerElem = refLeftContainer.value;
                const rightContainerElem = refRightContainer.value;
                const resizeBarElem = refColResizeBar.value;
                if (!resizeBarElem) {
                    return;
                }
                const isLeftFixed = fixedType === 'left';
                const isRightFixed = fixedType === 'right';
                const resizeTipElem = resizeBarElem.firstElementChild;
                const scrollbarXToTop = computeScrollbarXToTop.value;
                const { clientX: dragClientX } = evnt;
                const dragBtnElem = evnt.target;
                let cell = dragBtnElem.parentElement;
                let resizeColumn = column;
                const isDragGroupCol = column.children && column.children.length;
                if (isDragGroupCol) {
                    resizeColumn = getLastChildColumn(column);
                    if (isDragGroupCol) {
                        const trEl = cell ? cell.parentElement : null;
                        const theadEl = trEl ? trEl.parentElement : null;
                        cell = theadEl ? theadEl.querySelector(`.vxe-header--column[colid="${resizeColumn.id}"]`) : null;
                    }
                }
                if (!cell) {
                    return;
                }
                const cellParams = XEUtils.assign(params, { cell, $table: $xeTable });
                let dragLeft = 0;
                const tableRect = tableEl.getBoundingClientRect();
                const rightContainerRect = rightContainerElem ? rightContainerElem.getBoundingClientRect() : null;
                const cellRect = cell.getBoundingClientRect();
                const dragBtnRect = dragBtnElem.getBoundingClientRect();
                const dragBtnWidth = dragBtnElem.clientWidth;
                const dragBtnOffsetWidth = XEUtils.floor(dragBtnWidth / 2);
                const dragPosLeft = dragBtnRect.x - tableRect.x + dragBtnOffsetWidth;
                const minInterval = getColReMinWidth(cellParams) - dragBtnOffsetWidth; // 列之间的最小间距
                const maxInterval = getColReMaxWidth(cellParams); // 列之间的最大间距
                const dragMinLeft = isRightFixed ? 0 : (cellRect.x - tableRect.x + dragBtnWidth + minInterval);
                const dragMaxLeft = cellRect.x - tableRect.x + cell.clientWidth - minInterval;
                let fixedLeftRemainWidth = 0;
                let fixedRightRemainWidth = 0;
                if (isLeftFixed || isRightFixed) {
                    let isMach = false;
                    const fixedColumn = isLeftFixed ? leftList : rightList;
                    for (let i = 0; i < fixedColumn.length; i++) {
                        const item = fixedColumn[i];
                        if (isMach) {
                            fixedLeftRemainWidth += item.renderWidth;
                        }
                        else {
                            isMach = item.id === resizeColumn.id;
                            if (!isMach) {
                                fixedRightRemainWidth += item.renderWidth;
                            }
                        }
                    }
                }
                // 处理拖动事件
                const updateEvent = (evnt) => {
                    evnt.stopPropagation();
                    evnt.preventDefault();
                    const tableHeight = tableEl.clientHeight;
                    const offsetX = evnt.clientX - dragClientX;
                    let left = dragPosLeft + offsetX;
                    if (isLeftFixed) {
                        if (rightContainerRect) {
                            left = Math.min(left, rightContainerRect.x - tableRect.x - fixedLeftRemainWidth - minInterval);
                        }
                    }
                    else if (isRightFixed) {
                        if (leftContainerElem) {
                            left = Math.max(left, leftContainerElem.clientWidth + fixedRightRemainWidth + minInterval);
                        }
                        left = Math.min(left, dragMaxLeft);
                    }
                    dragLeft = Math.max(left, dragMinLeft);
                    // 最大宽
                    if (maxInterval > 1) {
                        dragLeft = Math.min(dragLeft, maxInterval + dragMinLeft - minInterval);
                    }
                    const resizeBarLeft = Math.max(1, dragLeft);
                    resizeBarElem.style.left = `${resizeBarLeft}px`;
                    resizeBarElem.style.top = `${scrollbarXToTop ? osbHeight : 0}px`;
                    resizeBarElem.style.height = `${scrollbarXToTop ? tableHeight - osbHeight : tableHeight}px`;
                    if (resizableOpts.showDragTip && resizeTipElem) {
                        resizeTipElem.textContent = getI18n('vxe.table.resizeColTip', [Math.floor(resizeColumn.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft))]);
                        const tableWrapperWidth = tableEl.clientWidth;
                        const resizeBarWidth = resizeBarElem.clientWidth;
                        const resizeTipWidth = resizeTipElem.clientWidth;
                        const resizeTipHeight = resizeTipElem.clientHeight;
                        let resizeTipLeft = -resizeTipWidth;
                        if (resizeBarLeft < resizeTipWidth + resizeBarWidth) {
                            resizeTipLeft = 0;
                        }
                        else if (resizeBarLeft > tableWrapperWidth) {
                            resizeTipLeft += tableWrapperWidth - resizeBarLeft;
                        }
                        resizeTipElem.style.left = `${resizeTipLeft}px`;
                        resizeTipElem.style.top = `${Math.min(tableHeight - resizeTipHeight, Math.max(0, evnt.clientY - tableRect.y - resizeTipHeight / 2))}px`;
                    }
                    reactData.isDragResize = true;
                };
                reactData.isDragResize = true;
                addClass(tableEl, 'col-drag--resize');
                resizeBarElem.style.display = 'block';
                document.onmousemove = updateEvent;
                document.onmouseup = function (evnt) {
                    document.onmousemove = null;
                    document.onmouseup = null;
                    resizeBarElem.style.display = 'none';
                    internalData._lastResizeTime = Date.now();
                    setTimeout(() => {
                        reactData.isDragResize = false;
                    }, 50);
                    const resizeWidth = resizeColumn.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft);
                    const resizeParams = Object.assign(Object.assign({}, params), { resizeWidth, resizeColumn });
                    if (resizableOpts.dragMode === 'fixed') {
                        visibleColumn.forEach(item => {
                            if (item.id !== resizeColumn.id) {
                                if (!item.resizeWidth) {
                                    item.resizeWidth = item.renderWidth;
                                }
                            }
                        });
                    }
                    if ($xeTable.handleColResizeCellAreaEvent) {
                        $xeTable.handleColResizeCellAreaEvent(evnt, resizeParams);
                    }
                    else {
                        resizeColumn.resizeWidth = resizeWidth;
                        handleUpdateColResize(evnt, resizeParams);
                    }
                    removeClass(tableEl, 'col-drag--resize');
                };
                updateEvent(evnt);
                if ($xeTable.closeMenu) {
                    $xeTable.closeMenu();
                }
            },
            handleColResizeDblclickEvent(evnt, params) {
                const resizableOpts = computeResizableOpts.value;
                const { isDblclickAutoWidth } = resizableOpts;
                const el = refElem.value;
                if (isDblclickAutoWidth && el) {
                    evnt.stopPropagation();
                    evnt.preventDefault();
                    const { fullColumnIdData } = internalData;
                    const { column } = params;
                    let resizeColumn = column;
                    if (column.children && column.children.length) {
                        XEUtils.eachTree(column.children, childColumn => {
                            resizeColumn = childColumn;
                        });
                    }
                    const colid = resizeColumn.id;
                    const colRest = fullColumnIdData[colid];
                    const dragBtnElem = evnt.target;
                    const cell = dragBtnElem.parentNode;
                    const cellParams = Object.assign(params, { cell, $table: $xeTable });
                    const colMinWidth = getColReMinWidth(cellParams);
                    const colMaxWidth = getColReMaxWidth(cellParams);
                    el.setAttribute('data-calc-col', 'Y');
                    let resizeWidth = calcColumnAutoWidth(resizeColumn, el);
                    el.removeAttribute('data-calc-col');
                    if (colRest) {
                        resizeWidth = Math.max(resizeWidth, colRest.width);
                    }
                    resizeWidth = Math.max(colMinWidth, resizeWidth);
                    if (colMaxWidth > 1) {
                        resizeWidth = Math.min(colMaxWidth, resizeWidth);
                    }
                    const resizeParams = Object.assign(Object.assign({}, params), { resizeWidth, resizeColumn });
                    reactData.isDragResize = false;
                    internalData._lastResizeTime = Date.now();
                    if ($xeTable.handleColResizeDblclickCellAreaEvent) {
                        $xeTable.handleColResizeDblclickCellAreaEvent(evnt, resizeParams);
                    }
                    else {
                        resizeColumn.resizeWidth = resizeWidth;
                        handleUpdateColResize(evnt, resizeParams);
                    }
                }
            },
            /**
             * @private
             */
            handleRowResizeMousedownEvent(evnt, params) {
                evnt.stopPropagation();
                evnt.preventDefault();
                const { row } = params;
                const { showOverflow } = props;
                const { overflowX, scrollbarWidth, overflowY, scrollbarHeight } = reactData;
                const { elemStore, fullAllDataRowIdData } = internalData;
                const osbWidth = overflowY ? scrollbarWidth : 0;
                const osbHeight = overflowX ? scrollbarHeight : 0;
                const scrollbarYToLeft = computeScrollbarYToLeft.value;
                const resizableOpts = computeResizableOpts.value;
                const rowOpts = computeRowOpts.value;
                const cellOpts = computeCellOpts.value;
                let tableEl = refElem.value;
                if ($xeGantt) {
                    const { refGanttContainerElem } = $xeGantt.getRefMaps();
                    const ganttContainerElem = refGanttContainerElem.value;
                    if (ganttContainerElem) {
                        tableEl = ganttContainerElem;
                    }
                }
                const resizeBarElem = refRowResizeBar.value;
                if (!resizeBarElem) {
                    return;
                }
                const { clientY: dragClientY } = evnt;
                const resizeTipElem = resizeBarElem.firstElementChild;
                const dragBtnElem = evnt.currentTarget;
                const tdEl = dragBtnElem.parentNode;
                const trEl = tdEl.parentNode;
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                if (!bodyScrollElem) {
                    return;
                }
                const rowid = getRowid($xeTable, row);
                const rowRest = fullAllDataRowIdData[rowid];
                if (!rowRest) {
                    return;
                }
                const defaultRowHeight = computeDefaultRowHeight.value;
                let currCellHeight = getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                if (!showOverflow) {
                    currCellHeight = tdEl.clientHeight;
                }
                const tableRect = tableEl.getBoundingClientRect();
                const trRect = trEl.getBoundingClientRect();
                const targetOffsetY = dragClientY - trRect.y - trEl.clientHeight;
                let resizeHeight = currCellHeight;
                const cellEl = tdEl.querySelector('.vxe-cell');
                let cellMinHeight = 0;
                if (cellEl) {
                    const cellStyle = getComputedStyle(cellEl);
                    cellMinHeight = Math.max(1, Math.ceil(XEUtils.toNumber(cellStyle.paddingTop) + XEUtils.toNumber(cellStyle.paddingBottom)));
                }
                const minTop = trRect.y - tableRect.y + cellMinHeight;
                // 处理拖动事件
                const updateEvent = (evnt) => {
                    evnt.stopPropagation();
                    evnt.preventDefault();
                    const rtWidth = tableEl.clientWidth - osbWidth;
                    const tableHeight = tableEl.clientHeight - osbHeight;
                    let dragTop = evnt.clientY - tableRect.y - targetOffsetY;
                    if (dragTop < minTop) {
                        dragTop = minTop;
                    }
                    else {
                        resizeHeight = Math.max(cellMinHeight, currCellHeight + evnt.clientY - dragClientY);
                    }
                    resizeBarElem.style.left = `${scrollbarYToLeft ? osbWidth : 0}px`;
                    resizeBarElem.style.top = `${dragTop}px`;
                    resizeBarElem.style.width = `${rtWidth}px`;
                    if (resizableOpts.showDragTip && resizeTipElem) {
                        resizeTipElem.textContent = getI18n('vxe.table.resizeRowTip', [resizeHeight]);
                        const resizeTipWidth = resizeTipElem.clientWidth;
                        const resizeTipHeight = resizeTipElem.clientHeight;
                        let resizeBarLeft = Math.max(2, evnt.clientX - tableRect.x);
                        let resizeBarTop = 0;
                        if (resizeBarLeft + resizeTipWidth >= rtWidth - 2) {
                            resizeBarLeft = rtWidth - resizeTipWidth - 2;
                        }
                        if (dragTop + resizeTipHeight >= tableHeight) {
                            resizeBarTop = tableHeight - (dragTop + resizeTipHeight);
                        }
                        resizeTipElem.style.left = `${resizeBarLeft}px`;
                        resizeTipElem.style.top = `${resizeBarTop}px`;
                    }
                    reactData.isDragResize = true;
                };
                reactData.isDragResize = true;
                addClass(tableEl, 'row-drag--resize');
                resizeBarElem.style.display = 'block';
                document.onmousemove = updateEvent;
                document.onmouseup = function (evnt) {
                    document.onmousemove = null;
                    document.onmouseup = null;
                    resizeBarElem.style.display = 'none';
                    internalData._lastResizeTime = Date.now();
                    setTimeout(() => {
                        reactData.isDragResize = false;
                    }, 50);
                    if (resizeHeight !== currCellHeight) {
                        const resizeParams = Object.assign(Object.assign({}, params), { resizeHeight, resizeRow: row });
                        internalData.isResizeCellHeight = true;
                        if ($xeTable.handleRowResizeCellAreaEvent) {
                            $xeTable.handleRowResizeCellAreaEvent(evnt, resizeParams);
                        }
                        else {
                            rowRest.resizeHeight = resizeHeight;
                            handleUpdateRowResize(evnt, resizeParams);
                            updateRowOffsetTop();
                        }
                    }
                    removeClass(tableEl, 'row-drag--resize');
                };
                updateEvent(evnt);
            },
            /**
             * @private
             */
            handleRowResizeDblclickEvent(evnt, params) {
                const resizableOpts = computeResizableOpts.value;
                const { isDblclickAutoHeight } = resizableOpts;
                const el = refElem.value;
                if (isDblclickAutoHeight && el) {
                    evnt.stopPropagation();
                    evnt.preventDefault();
                    const { editStore } = reactData;
                    const { fullAllDataRowIdData } = internalData;
                    const { actived } = editStore;
                    const { row } = params;
                    const rowid = getRowid($xeTable, row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    if (!rowRest) {
                        return;
                    }
                    const handleRsHeight = () => {
                        el.setAttribute('data-calc-row', 'Y');
                        const resizeHeight = calcCellAutoHeight(rowid, rowRest, el);
                        el.removeAttribute('data-calc-row');
                        const resizeParams = Object.assign(Object.assign({}, params), { resizeHeight, resizeRow: row });
                        reactData.isDragResize = false;
                        internalData._lastResizeTime = Date.now();
                        if ($xeTable.handleRowResizeDblclickCellAreaEvent) {
                            $xeTable.handleRowResizeDblclickCellAreaEvent(evnt, resizeParams);
                        }
                        else {
                            rowRest.resizeHeight = resizeHeight;
                            handleUpdateRowResize(evnt, resizeParams);
                        }
                    };
                    if (actived.row || actived.column) {
                        $xeTable.clearEdit().then(handleRsHeight);
                    }
                    else {
                        handleRsHeight();
                    }
                }
            },
            /**
             * @private
             */
            saveCustomStore(type) {
                const { customConfig } = props;
                const tableId = computeTableId.value;
                const customOpts = computeCustomOpts.value;
                const { updateStore, storage } = customOpts;
                const { isCustomAlign, isCustomHeaderAlign, isCustomFooterAlign, isCustomResizable, isCustomVisible, isCustomFixed, isCustomSort, isCustomAggGroup, isCustomAggFunc, isCustomPager } = handleCustomStoreConfig($xeTable);
                if (type !== 'reset') {
                    // fix:修复拖动列宽,重置按钮无法点击的问题
                    reactData.isCustomStatus = true;
                }
                if (storage &&
                    (customConfig ? isEnableConf(customOpts) : customOpts.enabled) &&
                    (isCustomAlign ||
                        isCustomHeaderAlign ||
                        isCustomFooterAlign ||
                        isCustomResizable ||
                        isCustomVisible ||
                        isCustomFixed ||
                        isCustomSort ||
                        isCustomAggGroup ||
                        isCustomAggFunc ||
                        isCustomPager)) {
                    if (!tableId) {
                        errLog('vxe.error.reqProp', ['id']);
                        return nextTick();
                    }
                    const storeData = type === 'reset'
                        ? {
                            pagerData: {},
                            alignData: {},
                            headerAlignData: {},
                            footerAlignData: {},
                            resizableData: {},
                            sortData: [],
                            visibleData: {},
                            fixedData: {},
                            aggGroupData: {},
                            aggFuncData: {}
                        }
                        : $xeTable.getCustomStoreData();
                    if (updateStore) {
                        return updateStore({
                            $table: $xeTable,
                            id: tableId,
                            type,
                            storeData
                        });
                    }
                    else {
                        setCustomStorageMap(tableId, type === 'reset' ? null : storeData);
                    }
                }
                return nextTick();
            },
            /**
             * @private
             */
            handleCustom() {
                const { mouseConfig } = props;
                if (mouseConfig) {
                    if ($xeTable.clearSelected) {
                        $xeTable.clearSelected();
                    }
                    if ($xeTable.clearCellAreas) {
                        $xeTable.clearCellAreas();
                        $xeTable.clearCopyCellArea();
                    }
                }
                $xeTable.analyColumnWidth();
                return $xeTable.refreshColumn(true);
            },
            handleUpdateDataQueue() {
                reactData.upDataFlag++;
            },
            handleRefreshColumnQueue() {
                reactData.reColumnFlag++;
            },
            handleFilterOptions(column) {
                if (column) {
                    const { filterStore } = reactData;
                    const { filterRender, filters } = column;
                    const filterOptions = filters || [];
                    const compConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null;
                    const frMethod = column.filterRecoverMethod || (compConf ? (compConf.tableFilterRecoverMethod || compConf.filterRecoverMethod) : null);
                    filterStore.column = column;
                    // 复原状态
                    filterOptions.forEach((option) => {
                        const { _checked, checked } = option;
                        option._checked = checked;
                        if (!checked && _checked !== checked) {
                            if (frMethod) {
                                frMethod({ option, column, $table: $xeTable });
                            }
                        }
                    });
                    $xeTable.checkFilterOptions();
                }
            },
            preventEvent(evnt, type, args, next, end) {
                let evntList = interceptor.get(type);
                // 兼容老版本
                if (!evntList.length && type === 'event.clearEdit') {
                    evntList = interceptor.get('event.clearActived');
                    if (evntList.length) {
                        warnLog('vxe.error.delEvent', ['event.clearActived', 'event.clearEdit']);
                    }
                }
                // 兼容老版本
                let rest = null;
                let isStop = false;
                for (let i = 0; i < evntList.length; i++) {
                    const func = evntList[i];
                    const fnRest = func(Object.assign({ $table: $xeTable, $grid: $xeGrid, gantt: $xeGantt, $event: evnt }, args));
                    if (fnRest === false) {
                        isStop = true;
                        break;
                    }
                    else if (fnRest && fnRest.status === false) {
                        rest = fnRest.result;
                        isStop = true;
                        break;
                    }
                }
                if (!isStop) {
                    if (next) {
                        rest = next();
                    }
                }
                if (end) {
                    end();
                }
                return rest;
            },
            updateCheckboxStatus() {
                const { treeConfig } = props;
                const { isRowGroupStatus } = reactData;
                const { afterTreeFullData, afterGroupFullData, selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
                const aggregateOpts = computeAggregateOpts.value;
                const treeOpts = computeTreeOpts.value;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField, indeterminateField, checkStrictly, checkMethod } = checkboxOpts;
                if (checkStrictly) {
                    return;
                }
                if (isRowGroupStatus || treeConfig) {
                    const { handleGetRowId } = createHandleGetRowId($xeTable);
                    const childRowMaps = {};
                    const childRowList = [];
                    if (isRowGroupStatus) {
                        // 行分组
                        const mapChildrenField = aggregateOpts.mapChildrenField;
                        if (mapChildrenField) {
                            XEUtils.eachTree(afterGroupFullData, (row) => {
                                const rowid = handleGetRowId(row);
                                const childList = row[mapChildrenField];
                                if (childList && childList.length && !childRowMaps[rowid]) {
                                    childRowMaps[rowid] = 1;
                                    childRowList.unshift([row, rowid, childList]);
                                }
                            }, { children: mapChildrenField });
                        }
                    }
                    else if (treeConfig) {
                        // 树结构
                        const { transform, mapChildrenField } = treeOpts;
                        XEUtils.eachTree(afterTreeFullData, (row) => {
                            const rowid = handleGetRowId(row);
                            const childList = row[transform ? mapChildrenField : childrenField];
                            if (childList && childList.length && !childRowMaps[rowid]) {
                                childRowMaps[rowid] = 1;
                                childRowList.unshift([row, rowid, childList]);
                            }
                            else {
                                if (indeterminateField) {
                                    XEUtils.set(row, indeterminateField, false);
                                }
                            }
                        }, { children: transform ? mapChildrenField : childrenField });
                    }
                    childRowList.forEach(vals => {
                        const row = vals[0];
                        const rowid = vals[1];
                        const childList = vals[2];
                        let sLen = 0; // 已选
                        let hLen = 0; // 半选
                        let vLen = 0; // 有效子行
                        const cLen = childList.length; // 子行
                        childList.forEach(checkMethod
                            ? (item) => {
                                const childRowid = handleGetRowId(item);
                                const isSelect = checkField ? XEUtils.get(item, checkField) : selectCheckboxMaps[childRowid];
                                if (checkMethod({ $table: $xeTable, row: item })) {
                                    if (isSelect) {
                                        sLen++;
                                    }
                                    else if (treeIndeterminateRowMaps[childRowid]) {
                                        hLen++;
                                    }
                                    vLen++;
                                }
                                else {
                                    if (isSelect) {
                                        sLen++;
                                    }
                                    else if (treeIndeterminateRowMaps[childRowid]) {
                                        hLen++;
                                    }
                                }
                            }
                            : item => {
                                const childRowid = handleGetRowId(item);
                                const isSelect = checkField ? XEUtils.get(item, checkField) : selectCheckboxMaps[childRowid];
                                if (isSelect) {
                                    sLen++;
                                }
                                else if (treeIndeterminateRowMaps[childRowid]) {
                                    hLen++;
                                }
                                vLen++;
                            });
                        let isSelected = false;
                        if (cLen > 0) {
                            if (vLen > 0) {
                                isSelected = (sLen > 0 || hLen > 0) && sLen >= vLen;
                            }
                            else {
                                // 如果存在子项禁用
                                if ((sLen > 0 && sLen >= vLen)) {
                                    isSelected = true;
                                }
                                else if (selectCheckboxMaps[rowid]) {
                                    isSelected = true;
                                }
                                else {
                                    isSelected = false;
                                }
                            }
                        }
                        else {
                            // 如果无子项
                            isSelected = selectCheckboxMaps[rowid];
                        }
                        const halfSelect = !isSelected && (sLen > 0 || hLen > 0);
                        if (checkField) {
                            XEUtils.set(row, checkField, isSelected);
                        }
                        if (indeterminateField) {
                            XEUtils.set(row, indeterminateField, halfSelect);
                        }
                        if (isSelected) {
                            if (!checkField) {
                                selectCheckboxMaps[rowid] = row;
                            }
                            if (treeIndeterminateRowMaps[rowid]) {
                                delete treeIndeterminateRowMaps[rowid];
                            }
                        }
                        else {
                            if (!checkField) {
                                if (selectCheckboxMaps[rowid]) {
                                    delete selectCheckboxMaps[rowid];
                                }
                            }
                            if (halfSelect) {
                                treeIndeterminateRowMaps[rowid] = row;
                            }
                            else {
                                if (treeIndeterminateRowMaps[rowid]) {
                                    delete treeIndeterminateRowMaps[rowid];
                                }
                            }
                        }
                    });
                }
                reactData.updateCheckboxFlag++;
            },
            updateAllCheckboxStatus() {
                const { treeConfig } = props;
                const { isRowGroupStatus } = reactData;
                const { afterFullData, afterTreeFullData, afterGroupFullData, checkboxReserveRowMap, selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
                const aggregateOpts = computeAggregateOpts.value;
                const { mapChildrenField } = aggregateOpts;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField, checkMethod, showReserveStatus } = checkboxOpts;
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                let sLen = 0; // 已选
                let dsLen = 0; // 禁用的已选
                let hLen = 0; // 半选
                let dhLen = 0; // 禁用的半选
                let vLen = 0; // 有效行
                const rootList = (treeConfig ? afterTreeFullData : (isRowGroupStatus ? afterGroupFullData : afterFullData));
                rootList.forEach(checkMethod
                    ? row => {
                        const childRowid = handleGetRowId(row);
                        const selected = checkField ? XEUtils.get(row, checkField) : selectCheckboxMaps[childRowid];
                        if (isRowGroupStatus && $xeTable.isAggregateRecord(row)) {
                            const childList = row[mapChildrenField || ''];
                            if (selected) {
                                vLen++;
                                sLen++;
                            }
                            else if (treeIndeterminateRowMaps[childRowid]) {
                                vLen++;
                                hLen++;
                            }
                            else if (childList && childList.length && childList.some(item => checkMethod({ $table: $xeTable, row: item }))) {
                                vLen++;
                            }
                        }
                        else if (checkMethod({ $table: $xeTable, row })) {
                            if (selected) {
                                sLen++;
                            }
                            else if (treeIndeterminateRowMaps[childRowid]) {
                                hLen++;
                            }
                            vLen++;
                        }
                        else {
                            if (selected) {
                                dsLen++;
                            }
                            else if (treeIndeterminateRowMaps[childRowid]) {
                                dhLen++;
                            }
                        }
                    }
                    : row => {
                        const childRowid = handleGetRowId(row);
                        const selected = checkField ? XEUtils.get(row, checkField) : selectCheckboxMaps[childRowid];
                        if (selected) {
                            sLen++;
                        }
                        else if (treeIndeterminateRowMaps[childRowid]) {
                            hLen++;
                        }
                        vLen++;
                    });
                const isSelected = rootList.length > 0 ? (vLen > 0 ? (sLen >= vLen) : (sLen >= rootList.length)) : false;
                let halfSelect = !isSelected && (sLen > 0 || hLen > 0 || dsLen > 0 || dhLen > 0);
                // 如果复选框启用保留记录,当保留数据存在时显示半选
                if (!isSelected && !halfSelect && showReserveStatus) {
                    halfSelect = !XEUtils.isEmpty(checkboxReserveRowMap);
                }
                reactData.isAllSelected = isSelected;
                reactData.isIndeterminate = halfSelect;
            },
            checkSelectionStatus() {
                $xeTable.updateCheckboxStatus();
                $xeTable.updateAllCheckboxStatus();
            },
            /**
             * 切换选中
             * 多选,行选中事件
             */
            handleBatchSelectRows(rows, checked, isForce) {
                const { treeConfig } = props;
                const { isRowGroupStatus } = reactData;
                const { selectCheckboxMaps } = internalData;
                const aggregateOpts = computeAggregateOpts.value;
                const treeOpts = computeTreeOpts.value;
                const { transform, mapChildrenField } = treeOpts;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField, checkStrictly, checkMethod } = checkboxOpts;
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                // indeterminateField 仅支持读取
                const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField;
                if (checkField) {
                    // 树结构
                    if ((treeConfig || isRowGroupStatus) && !checkStrictly) {
                        // 更新子节点状态
                        XEUtils.eachTree(rows, (row) => {
                            if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
                                XEUtils.set(row, checkField, checked);
                                if (indeterminateField) {
                                    XEUtils.set(row, indeterminateField, false);
                                }
                                handleCheckboxReserveRow(row, checked);
                            }
                        }, { children: transform ? mapChildrenField : childrenField });
                        reactData.updateCheckboxFlag++;
                        return;
                    }
                    // 列表
                    rows.forEach(row => {
                        if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
                            XEUtils.set(row, checkField, checked);
                            handleCheckboxReserveRow(row, checked);
                        }
                    });
                    reactData.updateCheckboxFlag++;
                    return;
                }
                // 树结构
                if (!checkStrictly) {
                    if (isRowGroupStatus) {
                        // 更新行分组节点状态
                        XEUtils.eachTree(rows, (row) => {
                            const rowid = handleGetRowId(row);
                            if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
                                if (checked) {
                                    selectCheckboxMaps[rowid] = row;
                                }
                                else {
                                    if (selectCheckboxMaps[rowid]) {
                                        delete selectCheckboxMaps[rowid];
                                    }
                                }
                                handleCheckboxReserveRow(row, checked);
                            }
                        }, { children: aggregateOpts.mapChildrenField });
                        reactData.updateCheckboxFlag++;
                        return;
                    }
                    else if (treeConfig) {
                        // 更新子节点状态
                        XEUtils.eachTree(rows, (row) => {
                            const rowid = handleGetRowId(row);
                            if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
                                if (checked) {
                                    selectCheckboxMaps[rowid] = row;
                                }
                                else {
                                    if (selectCheckboxMaps[rowid]) {
                                        delete selectCheckboxMaps[rowid];
                                    }
                                }
                                handleCheckboxReserveRow(row, checked);
                            }
                        }, { children: transform ? mapChildrenField : childrenField });
                        reactData.updateCheckboxFlag++;
                        return;
                    }
                }
                // 列表
                rows.forEach(row => {
                    const rowid = handleGetRowId(row);
                    if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
                        if (checked) {
                            if (!selectCheckboxMaps[rowid]) {
                                selectCheckboxMaps[rowid] = row;
                            }
                        }
                        else {
                            if (selectCheckboxMaps[rowid]) {
                                delete selectCheckboxMaps[rowid];
                            }
                        }
                        handleCheckboxReserveRow(row, checked);
                        reactData.updateCheckboxFlag++;
                    }
                });
            },
            /**
             * 即将移除
             * @deprecated
             */
            handleSelectRow({ row }, checked, isForce) {
                $xeTable.handleBatchSelectRows([row], checked, isForce);
            },
            handleUpdateHeaderMerge() {
                const { mergeHeaderList } = internalData;
                const { mergeMaps, mergeRowMaps, mergeColMaps } = buildMergeData(mergeHeaderList);
                internalData.mergeHeaderCellMaps = mergeMaps;
                internalData.mergeHeaderRowMaps = mergeRowMaps;
                internalData.mergeHeaderColMaps = mergeColMaps;
                reactData.mergeHeadFlag++;
            },
            /**
             * 处理合并
             */
            handleUpdateBodyMerge() {
                const { mergeBodyList } = internalData;
                const { mergeMaps, mergeRowMaps, mergeColMaps } = buildMergeData(mergeBodyList);
                internalData.mergeBodyCellMaps = mergeMaps;
                internalData.mergeBodyRowMaps = mergeRowMaps;
                internalData.mergeBodyColMaps = mergeColMaps;
                reactData.mergeBodyFlag++;
            },
            handleUpdateFooterMerge() {
                const { mergeFooterList } = internalData;
                const { mergeMaps, mergeRowMaps, mergeColMaps } = buildMergeData(mergeFooterList);
                internalData.mergeFooterCellMaps = mergeMaps;
                internalData.mergeFooterRowMaps = mergeRowMaps;
                internalData.mergeFooterColMaps = mergeColMaps;
                reactData.mergeFootFlag++;
            },
            handleAggregateSummaryData() {
                return $xeTable.refreshAggregateCalcValues();
            },
            triggerHeaderTitleEvent(evnt, iconParams, params) {
                const tipContent = iconParams.content || iconParams.message;
                if (tipContent) {
                    const { tooltipStore } = reactData;
                    const { column } = params;
                    const content = getFuncText(tipContent);
                    handleTargetEnterEvent(true);
                    tooltipStore.row = null;
                    tooltipStore.column = column;
                    tooltipStore.visible = true;
                    tooltipStore.currOpts = iconParams;
                    nextTick(() => {
                        const $tooltip = refTooltip.value;
                        if ($tooltip && $tooltip.open) {
                            $tooltip.open(evnt.currentTarget, content);
                        }
                    });
                }
            },
            /**
             * 触发表头 tooltip 事件
             */
            triggerHeaderTooltipEvent(evnt, params) {
                const { tooltipStore } = reactData;
                const headerTooltipOpts = computeHeaderTooltipOpts.value;
                const { column } = params;
                handleTargetEnterEvent(true);
                const titleElem = evnt.currentTarget;
                if (!titleElem) {
                    return;
                }
                const cWrapperEl = titleElem.parentElement;
                if (!cWrapperEl) {
                    return;
                }
                const cellEl = cWrapperEl.parentElement;
                if (!cellEl) {
                    return;
                }
                const thEl = cellEl.parentElement;
                if (!thEl) {
                    return;
                }
                if (tooltipStore.column !== column || !tooltipStore.visible) {
                    const ctEl = thEl.querySelector('.vxe-cell--title');
                    handleTooltip(evnt, headerTooltipOpts, 'header', thEl, (hasClass(thEl, 'col--ellipsis') ? ctEl : cWrapperEl) || cWrapperEl, ctEl || cellEl, params);
                }
            },
            /**
             * 触发单元格 tooltip 事件
             */
            triggerBodyTooltipEvent(evnt, params) {
                const { editConfig } = props;
                const { editStore } = reactData;
                const { tooltipStore } = reactData;
                const tooltipOpts = computeTooltipOpts.value;
                const editOpts = computeEditOpts.value;
                const { actived } = editStore;
                const { row, column } = params;
                const tdEl = evnt.currentTarget;
                handleTargetEnterEvent(tooltipStore.column !== column || tooltipStore.row !== row);
                // 单元格处于编辑状态时不触发提示框
                if (column.editRender && isEnableConf(editConfig)) {
                    // 如果是行编辑模式
                    if (editOpts.mode === 'row' && actived.row === row) {
                        return;
                    }
                    // 如果是单元格编辑模式
                    if (actived.row === row && actived.column === column) {
                        return;
                    }
                }
                if (tooltipStore.column !== column || tooltipStore.row !== row || !tooltipStore.visible) {
                    const ctEl = tdEl.querySelector('.vxe-cell--wrapper');
                    let ovEl = null;
                    let tipEl = tdEl.querySelector(column.type === 'html' ? '.vxe-cell--html' : '.vxe-cell--label');
                    if (column.treeNode) {
                        ovEl = tdEl.querySelector('.vxe-tree-cell');
                    }
                    if (!tipEl) {
                        tipEl = ctEl;
                    }
                    handleTooltip(evnt, tooltipOpts, 'body', tdEl, ovEl || ctEl, tipEl, params);
                }
            },
            /**
             * 触发表尾 tooltip 事件
             */
            triggerFooterTooltipEvent(evnt, params) {
                const { column } = params;
                const { tooltipStore } = reactData;
                const footerTooltipOpts = computeFooterTooltipOpts.value;
                const tdEl = evnt.currentTarget;
                handleTargetEnterEvent(tooltipStore.column !== column || !!tooltipStore.row);
                if (tooltipStore.column !== column || !tooltipStore.visible) {
                    const ctEl = tdEl.querySelector('.vxe-cell--wrapper');
                    let ovEl = null;
                    let tipEl = tdEl.querySelector(column.type === 'html' ? '.vxe-cell--html' : '.vxe-cell--label');
                    if (column.type === 'html') {
                        ovEl = tdEl.querySelector('.vxe-cell--html');
                    }
                    if (!tipEl) {
                        tipEl = ctEl;
                    }
                    handleTooltip(evnt, footerTooltipOpts, 'footer', tdEl, ovEl || ctEl, tipEl, params);
                }
            },
            handleTargetLeaveEvent() {
                const tooltipOpts = computeTooltipOpts.value;
                let $tooltip = refTooltip.value;
                if ($tooltip && $tooltip.setActived) {
                    $tooltip.setActived(false);
                }
                if (tooltipOpts.enterable) {
                    internalData.tooltipTimeout = setTimeout(() => {
                        $tooltip = refTooltip.value;
                        if ($tooltip && $tooltip.isActived && !$tooltip.isActived()) {
                            $xeTable.closeTooltip();
                        }
                    }, tooltipOpts.leaveDelay);
                }
                else {
                    $xeTable.closeTooltip();
                }
            },
            triggerHeaderCellClickEvent(evnt, params) {
                const { _lastResizeTime } = internalData;
                const sortOpts = computeSortOpts.value;
                const columnOpts = computeColumnOpts.value;
                const currentColumnOpts = computeCurrentColumnOpts.value;
                const { column } = params;
                const cell = evnt.currentTarget;
                const triggerResizable = _lastResizeTime && _lastResizeTime > Date.now() - 300;
                const triggerSort = getEventTargetNode(evnt, cell, 'vxe-cell--sort').flag;
                const triggerFilter = getEventTargetNode(evnt, cell, 'vxe-cell--filter').flag;
                if (sortOpts.trigger === 'cell' && !(triggerResizable || triggerSort || triggerFilter)) {
                    $xeTable.triggerSortEvent(evnt, column, getNextSortOrder(column));
                }
                if ($xeGantt) {
                    const ganttReactData = $xeGantt.reactData;
                    ganttReactData.activeBarRowid = null;
                }
                dispatchEvent('header-cell-click', Object.assign({ triggerResizable, triggerSort, triggerFilter, cell }, params), evnt);
                if ((columnOpts.isCurrent || props.highlightCurrentColumn) && (!currentColumnOpts.trigger || ['header', 'default'].includes(currentColumnOpts.trigger))) {
                    $xeTable.triggerCurrentColumnEvent(evnt, params);
                }
            },
            triggerHeaderCellDblclickEvent(evnt, params) {
                dispatchEvent('header-cell-dblclick', Object.assign({ cell: evnt.currentTarget }, params), evnt);
            },
            /**
             * 列点击事件
             * 如果是单击模式,则激活为编辑状态
             * 如果是双击模式,则单击后选中状态
             */
            triggerCellClickEvent(evnt, params) {
                const { treeConfig, highlightCurrentRow, highlightCurrentColumn, editConfig, aggregateConfig, rowGroupConfig } = props;
                const { editStore, isDragResize, expandColumn, checkboxColumn, radioColumn } = reactData;
                if (isDragResize) {
                    return;
                }
                const expandOpts = computeExpandOpts.value;
                const editOpts = computeEditOpts.value;
                const treeOpts = computeTreeOpts.value;
                const radioOpts = computeRadioOpts.value;
                const checkboxOpts = computeCheckboxOpts.value;
                const keyboardOpts = computeKeyboardOpts.value;
                const aggregateOpts = computeAggregateOpts.value;
                const rowOpts = computeRowOpts.value;
                const columnOpts = computeColumnOpts.value;
                const currentColumnOpts = computeCurrentColumnOpts.value;
                const { actived, focused } = editStore;
                const { row, column } = params;
                const { type, treeNode, rowGroupNode } = column;
                const isRadioType = type === 'radio';
                const isCheckboxType = type === 'checkbox';
                const isExpandType = type === 'expand';
                const cell = evnt.currentTarget;
                const triggerRadio = isRadioType && getEventTargetNode(evnt, cell, 'vxe-cell--radio').flag;
                const triggerCheckbox = isCheckboxType && getEventTargetNode(evnt, cell, 'vxe-cell--checkbox').flag;
                const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-cell--tree-btn').flag;
                const triggerExpandNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-table--expanded').flag;
                const triggerRowGroupNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-row-group--node-btn').flag;
                params = Object.assign({ cell, triggerRadio, triggerCheckbox, triggerTreeNode, triggerExpandNode }, params);
                if (!triggerCheckbox && !triggerRadio) {
                    // 如果是展开行
                    if (!triggerExpandNode && ((expandColumn && expandOpts.trigger === 'row') || (isExpandType && expandOpts.trigger === 'cell'))) {
                        $xeTable.triggerRowExpandEvent(evnt, params);
                    }
                    // 如果是树形表格
                    if (treeConfig && (treeOpts.trigger === 'row' || (treeNode && treeOpts.trigger === 'cell'))) {
                        $xeTable.triggerTreeExpandEvent(evnt, params);
                    }
                    // 如果是行分组
                    if ((aggregateConfig || rowGroupConfig) && (aggregateOpts.trigger === 'row' || (rowGroupNode && aggregateOpts.trigger === 'cell'))) {
                        $xeTable.triggerRowGroupExpandEvent(evnt, params);
                    }
                }
                // 如果点击了树节点
                if (!triggerTreeNode) {
                    if (!triggerExpandNode && !triggerRowGroupNode) {
                        // 如果是当前行
                        if (rowOpts.isCurrent || highlightCurrentRow) {
                            if (!triggerCheckbox && !triggerRadio) {
                                $xeTable.triggerCurrentRowEvent(evnt, params);
                            }
                        }
                        // 如果是当前列
                        if ((columnOpts.isCurrent || highlightCurrentColumn) && (!currentColumnOpts.trigger || ['cell', 'default'].includes(currentColumnOpts.trigger))) {
                            if (!triggerCheckbox && !triggerRadio) {
                                $xeTable.triggerCurrentColumnEvent(evnt, params);
                            }
                        }
                        // 如果是单选框
                        if (!triggerRadio && ((radioColumn && radioOpts.trigger === 'row') || (isRadioType && radioOpts.trigger === 'cell'))) {
                            $xeTable.triggerRadioRowEvent(evnt, params);
                        }
                        // 如果是复选框
                        if (!triggerCheckbox && ((checkboxColumn && checkboxOpts.trigger === 'row') || (isCheckboxType && checkboxOpts.trigger === 'cell'))) {
                            $xeTable.handleToggleCheckRowEvent(evnt, params);
                        }
                    }
                    // 如果设置了单元格选中功能,则不会使用点击事件去处理(只能支持双击模式)
                    if (isEnableConf(editConfig)) {
                        // 记录点击输入框聚焦状态
                        if (keyboardOpts.arrowCursorLock && evnt && editOpts.mode === 'cell' && evnt.target && /^input|textarea$/i.test(evnt.target.tagName)) {
                            focused.column = column;
                            focused.row = row;
                        }
                        if (editOpts.trigger === 'manual') {
                            if (actived.args && actived.row === row && column !== actived.column) {
                                if (editOpts.mode === 'row') {
                                    handleChangeCell(evnt, params);
                                }
                                else {
                                    checkValidate('blur')
                                        .catch((e) => e);
                                }
                            }
                        }
                        else if (!actived.args || row !== actived.row || column !== actived.column) {
                            if (editOpts.trigger === 'click') {
                                handleChangeCell(evnt, params);
                            }
                            else if (editOpts.trigger === 'dblclick') {
                                if (editOpts.mode === 'row' && actived.row === row) {
                                    handleChangeCell(evnt, params);
                                }
                            }
                        }
                    }
                }
                // 如果是双击编辑模式
                if (isEnableConf(editConfig) && editOpts.trigger === 'dblclick') {
                    if (actived.row && actived.column) {
                        if (editOpts.mode === 'row') {
                            if (!$xeTable.eqRow(actived.row, row)) {
                                $xeTable.handleClearEdit(evnt);
                            }
                        }
                        else if (editOpts.mode === 'cell') {
                            if (!$xeTable.eqRow(actived.row, row) || actived.column.id !== column.id) {
                                $xeTable.handleClearEdit(evnt);
                            }
                        }
                    }
                }
                if ($xeGantt) {
                    const ganttReactData = $xeGantt.reactData;
                    ganttReactData.activeBarRowid = null;
                }
                dispatchEvent('cell-click', params, evnt);
            },
            /**
             * 列双击点击事件
             * 如果是双击模式,则激活为编辑状态
             */
            triggerCellDblclickEvent(evnt, params) {
                const { editConfig } = props;
                const { editStore, isDragResize } = reactData;
                if (isDragResize) {
                    return;
                }
                const editOpts = computeEditOpts.value;
                const { actived } = editStore;
                const cell = evnt.currentTarget;
                params = Object.assign({ cell }, params);
                if (isEnableConf(editConfig) && editOpts.trigger === 'dblclick') {
                    if (!actived.args || evnt.currentTarget !== actived.args.cell) {
                        if (editOpts.mode === 'row') {
                            checkValidate('blur')
                                .catch((e) => e)
                                .then(() => {
                                $xeTable.handleEdit(params, evnt)
                                    .then(() => checkValidate('change'))
                                    .catch((e) => e);
                            });
                        }
                        else if (editOpts.mode === 'cell') {
                            $xeTable.handleEdit(params, evnt)
                                .then(() => checkValidate('change'))
                                .catch((e) => e);
                        }
                    }
                }
                dispatchEvent('cell-dblclick', params, evnt);
            },
            triggerFooterCellClickEvent(evnt, params) {
                const cell = evnt.currentTarget;
                params = Object.assign({ cell }, params);
                if ($xeGantt) {
                    const ganttReactData = $xeGantt.reactData;
                    ganttReactData.activeBarRowid = null;
                }
                $xeTable.dispatchEvent('footer-cell-click', params, evnt);
            },
            triggerFooterCellDblclickEvent(evnt, params) {
                const cell = evnt.currentTarget;
                params = Object.assign({ cell }, params);
                $xeTable.dispatchEvent('footer-cell-dblclick', params, evnt);
            },
            handleToggleCheckRowEvent(evnt, params) {
                const { selectCheckboxMaps } = internalData;
                const checkboxOpts = computeCheckboxOpts.value;
                const { checkField, trigger } = checkboxOpts;
                const { row } = params;
                if (trigger === 'manual') {
                    return;
                }
                let checked = false;
                if (checkField) {
                    checked = !XEUtils.get(row, checkField);
                }
                else {
                    checked = !selectCheckboxMaps[getRowid($xeTable, row)];
                }
                if (evnt) {
                    $xeTable.triggerCheckRowEvent(evnt, params, checked);
                }
                else {
                    $xeTable.handleBatchSelectRows([row], checked);
                    $xeTable.checkSelectionStatus();
                }
            },
            triggerCheckRowEvent(evnt, params, checked) {
                const { treeConfig } = props;
                const { row } = params;
                const { isRowGroupStatus } = reactData;
                const { fullAllDataRowIdData, afterFullData, afterTreeFullData, afterGroupFullData } = internalData;
                const checkboxOpts = computeCheckboxOpts.value;
                const aggregateOpts = computeAggregateOpts.value;
                const treeOpts = computeTreeOpts.value;
                const { checkMethod, trigger, checkStrictly } = checkboxOpts;
                if (trigger === 'manual') {
                    return;
                }
                evnt.stopPropagation();
                if (checkboxOpts.isShiftKey && evnt.shiftKey) {
                    const { handleGetRowId } = createHandleGetRowId($xeTable);
                    const checkboxRecords = $xeTable.getCheckboxRecords();
                    let currSeq = -1;
                    let currRow = null;
                    const currRowid = handleGetRowId(row);
                    const rowRest = fullAllDataRowIdData[currRowid];
                    if (rowRest) {
                        currRow = rowRest.row;
                        currSeq = rowRest._seq;
                    }
                    if (currRow && checkboxRecords.length) {
                        let rangeRows = [];
                        let firstSeq = -1;
                        let firstRow = null;
                        let firstRowid = '';
                        let lastSeq = -1;
                        let lastRow = null;
                        let lastRowid = '';
                        // 根据序号取出范围最小/最大的行
                        const selectMaps = {};
                        checkboxRecords.forEach(item => {
                            const rowid = handleGetRowId(item);
                            const rowRest = fullAllDataRowIdData[rowid];
                            if (rowRest) {
                                if (!firstRow || firstSeq > rowRest._seq) {
                                    firstRowid = rowRest.rowid;
                                    firstRow = rowRest.row;
                                    firstSeq = rowRest._seq;
                                }
                                if (!lastRow || lastSeq < rowRest._seq) {
                                    lastRowid = rowRest.rowid;
                                    lastRow = rowRest.row;
                                    lastSeq = rowRest._seq;
                                }
                            }
                            selectMaps[rowid] = item;
                        });
                        // 如果已选只有一条并选择当前则跳过
                        if (firstRow && lastRow && (checkboxRecords.length > 1 || currRowid !== firstRowid) && (Math.abs(firstSeq - lastSeq) > 1 || Math.abs(currSeq - firstSeq) > 1 || Math.abs(currSeq - lastSeq) > 1)) {
                            // 树与分组
                            if (treeConfig || isRowGroupStatus) {
                                const { transform } = treeOpts;
                                const childrenField = treeOpts.children || treeOpts.childrenField;
                                const iteratorChildField = treeConfig ? (transform ? treeOpts.mapChildrenField : childrenField) : aggregateOpts.mapChildrenField;
                                let isMatchFirst = false;
                                let matchStartRowid = '';
                                let matchEndRowid = '';
                                const handleGetChildRowid = (rowid, isLast) => {
                                    const rowRest = fullAllDataRowIdData[rowid];
                                    if (rowRest) {
                                        const item = rowRest.row;
                                        const childList = item[iteratorChildField];
                                        if (childList && childList.length) {
                                            const targetRow = isLast ? XEUtils.last(childList) : XEUtils.first(childList);
                                            return handleGetChildRowid(handleGetRowId(targetRow), isLast);
                                        }
                                    }
                                    return rowid;
                                };
                                const handleGetSelectParentRowid = (rowid) => {
                                    const rowRest = fullAllDataRowIdData[rowid];
                                    if (rowRest) {
                                        const parentItem = rowRest.parent;
                                        if (parentItem) {
                                            const parentRowid = handleGetRowId(parentItem);
                                            if (selectMaps[parentRowid]) {
                                                return handleGetSelectParentRowid(parentRowid);
                                            }
                                        }
                                    }
                                    return rowid;
                                };
                                const handleGetRootRow = (row) => {
                                    const rowid = handleGetRowId(row);
                                    if (rowid) {
                                        const rest = fullAllDataRowIdData[rowid];
                                        if (rest) {
                                            return rest.parent ? handleGetRootRow(rest.parent) : rest;
                                        }
                                    }
                                    return null;
                                };
                                if (currSeq < firstSeq) {
                                    matchStartRowid = handleGetChildRowid(currRowid, 0);
                                    matchEndRowid = handleGetChildRowid(firstRowid, 1);
                                }
                                else {
                                    if (currSeq > lastSeq) {
                                        matchStartRowid = handleGetSelectParentRowid(lastRowid);
                                    }
                                    else {
                                        matchStartRowid = handleGetChildRowid(firstRowid, 0);
                                    }
                                    matchEndRowid = handleGetChildRowid(currRowid, 1);
                                }
                                const handleRangeRow = (item) => {
                                    const rowid = handleGetRowId(item);
                                    const childList = item[iteratorChildField];
                                    if (!isMatchFirst && rowid === matchStartRowid) {
                                        isMatchFirst = true;
                                    }
                                    // 如果是父子关联,则排除父节点
                                    if (isMatchFirst && (checkStrictly || !childList || !childList.length)) {
                                        rangeRows.push(item);
                                    }
                                    // break
                                    return rowid === matchEndRowid;
                                };
                                if (treeConfig) {
                                    const matchStartRowRest = fullAllDataRowIdData[matchStartRowid];
                                    const firstRootRowRest = matchStartRowRest ? handleGetRootRow(matchStartRowRest.row) : null;
                                    if (firstRootRowRest) {
                                        // 优化查找复杂度
                                        XEUtils.findTree(afterTreeFullData.slice(firstRootRowRest.treeIndex), handleRangeRow, { children: iteratorChildField });
                                    }
                                    else {
                                        XEUtils.findTree(afterTreeFullData, handleRangeRow, { children: iteratorChildField });
                                    }
                                }
                                else {
                                    XEUtils.findTree(afterGroupFullData, handleRangeRow, { children: iteratorChildField });
                                }
                            }
                            else {
                                const _currRowIndex = $xeTable.getVTRowIndex(currRow);
                                const _firstRowIndex = $xeTable.getVTRowIndex(firstRow);
                                const _lastRowIndex = $xeTable.getVTRowIndex(lastRow);
                                if (_currRowIndex < _firstRowIndex) {
                                    rangeRows = afterFullData.slice(_currRowIndex, _firstRowIndex + 1);
                                }
                                else if (_currRowIndex > _lastRowIndex) {
                                    rangeRows = afterFullData.slice(_lastRowIndex, _currRowIndex + 1);
                                }
                                else {
                                    rangeRows = afterFullData.slice(_firstRowIndex, _currRowIndex + 1);
                                }
                            }
                            $xeTable.setAllCheckboxRow(false);
                            nextTick(() => {
                                handleCheckedCheckboxRow(rangeRows, true, false);
                            });
                            dispatchEvent('checkbox-range-select', Object.assign({ rangeRecords: rangeRows }, params), evnt);
                        }
                    }
                }
                if (!checkMethod || checkMethod({ $table: $xeTable, row })) {
                    $xeTable.handleBatchSelectRows([row], checked);
                    $xeTable.checkSelectionStatus();
                    dispatchEvent('checkbox-change', Object.assign({
                        records: () => $xeTable.getCheckboxRecords(),
                        reserves: () => $xeTable.getCheckboxReserveRecords(),
                        indeterminates: () => $xeTable.getCheckboxIndeterminateRecords(),
                        checked
                    }, params), evnt);
                }
            },
            /**
             * 多选,选中所有事件
             */
            triggerCheckAllEvent(evnt, value) {
                const checkboxOpts = computeCheckboxOpts.value;
                const { trigger } = checkboxOpts;
                if (trigger === 'manual') {
                    return;
                }
                if (evnt) {
                    evnt.stopPropagation();
                }
                handleCheckAllEvent(evnt, value);
            },
            /**
             * 单选,行选中事件
             */
            triggerRadioRowEvent(evnt, params) {
                const { selectRadioRow: oldValue } = reactData;
                const { row } = params;
                const radioOpts = computeRadioOpts.value;
                const { trigger, strict, checkMethod } = radioOpts;
                if (trigger === 'manual') {
                    return;
                }
                evnt.stopPropagation();
                if (!checkMethod || checkMethod({ $table: $xeTable, row })) {
                    let newValue = row;
                    let isChange = oldValue !== newValue;
                    if (strict) {
                        handleCheckedRadioRow(newValue, false);
                    }
                    else {
                        if (oldValue === newValue) {
                            newValue = null;
                        }
                        isChange = oldValue !== newValue;
                        if (isChange && newValue) {
                            handleCheckedRadioRow(newValue, false);
                        }
                        else {
                            newValue = null;
                            $xeTable.clearRadioRow();
                        }
                    }
                    if (isChange) {
                        dispatchEvent('radio-change', Object.assign({ oldValue, newValue, selected: !!newValue }, params), evnt);
                    }
                }
            },
            triggerCurrentColumnEvent(evnt, params) {
                const { currentColumn: oldValue } = reactData;
                const columnOpts = computeColumnOpts.value;
                const currentColumnOpts = computeCurrentColumnOpts.value;
                const beforeRowMethod = currentColumnOpts.beforeSelectMethod || columnOpts.currentMethod;
                let newValue = params.column;
                const { trigger, strict } = currentColumnOpts;
                if (trigger === 'manual') {
                    return;
                }
                let isChange = oldValue !== newValue;
                if (!beforeRowMethod || beforeRowMethod({ column: newValue, $table: $xeTable })) {
                    if (strict) {
                        $xeTable.setCurrentColumn(newValue);
                    }
                    else {
                        if (oldValue === newValue) {
                            newValue = null;
                        }
                        isChange = oldValue !== newValue;
                        if (isChange && newValue) {
                            $xeTable.setCurrentColumn(newValue);
                        }
                        else {
                            newValue = null;
                            $xeTable.clearCurrentColumn();
                        }
                    }
                    if (isChange) {
                        dispatchEvent('current-column-change', Object.assign({ oldValue, newValue, selected: !!newValue }, params), evnt);
                    }
                }
                else {
                    dispatchEvent('current-column-disabled', params, evnt);
                }
            },
            triggerCurrentRowEvent(evnt, params) {
                const { currentRow: oldValue } = internalData;
                const rowOpts = computeRowOpts.value;
                const currentRowOpts = computeCurrentRowOpts.value;
                const beforeRowMethod = currentRowOpts.beforeSelectMethod || rowOpts.currentMethod;
                let { row: newValue } = params;
                const { trigger, strict } = currentRowOpts;
                if (trigger === 'manual') {
                    return;
                }
                let isChange = oldValue !== newValue;
                if (!beforeRowMethod || beforeRowMethod({ row: newValue, $table: $xeTable })) {
                    if (strict) {
                        $xeTable.setCurrentRow(newValue);
                    }
                    else {
                        if (oldValue === newValue) {
                            newValue = null;
                        }
                        isChange = oldValue !== newValue;
                        if (isChange && newValue) {
                            $xeTable.setCurrentRow(newValue);
                        }
                        else {
                            newValue = null;
                            $xeTable.clearCurrentRow();
                        }
                    }
                    if (isChange) {
                        dispatchEvent('current-row-change', Object.assign({ oldValue, newValue, selected: !!newValue }, params), evnt);
                        // 已废弃
                        dispatchEvent('current-change', Object.assign({ oldValue, newValue }, params), evnt);
                    }
                }
                else {
                    dispatchEvent('current-row-disabled', params, evnt);
                }
            },
            /**
             * 展开行事件
             */
            triggerRowExpandEvent(evnt, params) {
                const { expandColumn } = reactData;
                const { rowExpandLazyLoadedMaps } = internalData;
                const expandOpts = computeExpandOpts.value;
                const { row } = params;
                const { lazy, trigger } = expandOpts;
                if (trigger === 'manual') {
                    return;
                }
                evnt.stopPropagation();
                const rowid = getRowid($xeTable, row);
                if (!lazy || !rowExpandLazyLoadedMaps[rowid]) {
                    const expanded = !$xeTable.isRowExpandByRow(row);
                    const columnIndex = expandColumn ? $xeTable.getColumnIndex(expandColumn) : -1;
                    const $columnIndex = expandColumn ? $xeTable.getVMColumnIndex(expandColumn) : -1;
                    $xeTable.setRowExpand(row, expanded);
                    dispatchEvent('toggle-row-expand', {
                        expanded,
                        column: expandColumn,
                        columnIndex,
                        $columnIndex,
                        row,
                        rowIndex: $xeTable.getRowIndex(row),
                        $rowIndex: $xeTable.getVMRowIndex(row)
                    }, evnt);
                }
            },
            /**
             * 行分组事件
             */
            triggerRowGroupExpandEvent(evnt, params) {
                const { rowGroupExpandedMaps } = internalData;
                const aggregateOpts = computeAggregateOpts.value;
                const { row, column } = params;
                const { trigger } = aggregateOpts;
                if (trigger === 'manual') {
                    return;
                }
                evnt.stopPropagation();
                const rowid = getRowid($xeTable, row);
                const expanded = !rowGroupExpandedMaps[rowid];
                const columnIndex = $xeTable.getColumnIndex(column);
                const $columnIndex = $xeTable.getVMColumnIndex(column);
                $xeTable.setRowGroupExpand(row, expanded);
                dispatchEvent('toggle-row-group-expand', { expanded, column, columnIndex, $columnIndex, row }, evnt);
            },
            /**
             * 展开树节点事件
             */
            triggerTreeExpandEvent(evnt, params) {
                const { treeExpandLazyLoadedMaps, treeEATime } = internalData;
                const treeOpts = computeTreeOpts.value;
                const { row, column } = params;
                const { lazy, trigger, accordion } = treeOpts;
                if (trigger === 'manual') {
                    return;
                }
                evnt.stopPropagation();
                const rowid = getRowid($xeTable, row);
                if (!lazy || !treeExpandLazyLoadedMaps[rowid]) {
                    const expanded = !$xeTable.isTreeExpandByRow(row);
                    const columnIndex = $xeTable.getColumnIndex(column);
                    const $columnIndex = $xeTable.getVMColumnIndex(column);
                    if (treeEATime) {
                        clearTimeout(treeEATime);
                    }
                    $xeTable.setTreeExpand(row, expanded).then(() => {
                        if (accordion) {
                            internalData.treeEATime = setTimeout(() => {
                                internalData.treeEATime = undefined;
                                $xeTable.scrollToRow(row);
                            }, 30);
                        }
                    });
                    dispatchEvent('toggle-tree-expand', { expanded, column, columnIndex, $columnIndex, row }, evnt);
                }
            },
            handleColumnSortEvent(evnt, column) {
                const { mouseConfig } = props;
                const mouseOpts = computeMouseOpts.value;
                const { field, sortable, order } = column;
                if (sortable) {
                    const params = { $table: $xeTable, $event: evnt, column, field, property: field, order, sortList: $xeTable.getSortColumns(), sortTime: column.sortTime };
                    if (mouseConfig && mouseOpts.area && $xeTable.handleSortEvent) {
                        $xeTable.handleSortEvent(evnt, params);
                    }
                    if (!order) {
                        dispatchEvent('clear-sort', params, evnt);
                    }
                    dispatchEvent('sort-change', params, evnt);
                }
            },
            /**
             * 点击排序事件
             */
            triggerSortEvent(evnt, column, order) {
                const sortOpts = computeSortOpts.value;
                const { multiple, allowClear } = sortOpts;
                const { field, sortable } = column;
                if (sortable) {
                    if (!order || column.order === order) {
                        if (allowClear) {
                            $xeTable.clearSort(multiple ? column : null);
                        }
                    }
                    else {
                        $xeTable.sort({ field, order });
                    }
                    $xeTable.handleColumnSortEvent(evnt, column);
                }
            },
            handleCellRuleUpdateStatus(type, cellParams, cellValue) {
                const { validStore } = reactData;
                const { row, column } = cellParams;
                if ($xeTable.hasCellRules) {
                    if ($xeTable.hasCellRules(type, row, column)) {
                        const cell = $xeTable.getCellElement(row, column);
                        if (cell) {
                            const customVal = !XEUtils.isUndefined(cellValue);
                            return $xeTable.validCellRules(type, row, column, cellValue)
                                .then(() => {
                                if (customVal && validStore.visible) {
                                    setCellValue(row, column, cellValue);
                                }
                                $xeTable.clearValidate(row, column);
                            })
                                .catch(({ rule }) => {
                                if (customVal) {
                                    setCellValue(row, column, cellValue);
                                }
                                $xeTable.showValidTooltip({ rule, row, column, cell });
                            });
                        }
                    }
                }
                return nextTick();
            },
            /**
             * 表头单元格按下事件
             */
            triggerHeaderCellMousedownEvent(evnt, params) {
                const { mouseConfig } = props;
                const mouseOpts = computeMouseOpts.value;
                const columnOpts = computeColumnOpts.value;
                const columnDragOpts = computeColumnDragOpts.value;
                const { trigger, isCrossDrag, isPeerDrag, disabledMethod } = columnDragOpts;
                const cell = evnt.currentTarget;
                const triggerInput = cell && cell.tagName && cell.tagName.toLowerCase() === 'input';
                const triggerCheckbox = getEventTargetNode(evnt, cell, 'vxe-cell--checkbox').flag;
                const triggerSort = getEventTargetNode(evnt, cell, 'vxe-cell--sort').flag;
                const triggerFilter = getEventTargetNode(evnt, cell, 'vxe-cell--filter').flag;
                let triggerDrag = false;
                const isColDragCell = columnOpts.drag && trigger === 'cell';
                if (!(triggerInput || triggerCheckbox || triggerSort || triggerFilter)) {
                    const { column } = params;
                    if (isColDragCell && !column.fixed && (isCrossDrag || isPeerDrag || !column.parentId) && !(disabledMethod && disabledMethod(params))) {
                        triggerDrag = true;
                        $xeTable.handleHeaderCellDragMousedownEvent(evnt, params);
                    }
                }
                if (!triggerDrag && mouseConfig && mouseOpts.area && $xeTable.handleHeaderCellAreaMouseDnEvent) {
                    $xeTable.handleHeaderCellAreaMouseDnEvent(evnt, Object.assign({ cell, triggerSort, triggerFilter }, params));
                }
                $xeTable.focus();
                if ($xeTable.closeMenu) {
                    $xeTable.closeMenu();
                }
            },
            /**
             * 单元格按下事件
             */
            triggerCellMousedownEvent(evnt, params) {
                const { column } = params;
                const { type, treeNode } = column;
                const isRadioType = type === 'radio';
                const isCheckboxType = type === 'checkbox';
                const isExpandType = type === 'expand';
                const rowOpts = computeRowOpts.value;
                const rowDragOpts = computeRowDragOpts.value;
                const { trigger, isCrossDrag, isPeerDrag, disabledMethod } = rowDragOpts;
                const cell = evnt.currentTarget;
                params.cell = cell;
                const triggerInput = cell && cell.tagName && cell.tagName.toLowerCase() === 'input';
                const triggerRadio = isRadioType && getEventTargetNode(evnt, cell, 'vxe-cell--radio').flag;
                const triggerCheckbox = isCheckboxType && getEventTargetNode(evnt, cell, 'vxe-cell--checkbox').flag;
                const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-cell--tree-btn').flag;
                const triggerExpandNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-table--expanded').flag;
                let isColDragCell = false;
                if (rowOpts.drag) {
                    isColDragCell = trigger === 'row' || (column.dragSort && trigger === 'cell');
                }
                let triggerDrag = false;
                if (!(triggerInput || triggerRadio || triggerCheckbox || triggerTreeNode || triggerExpandNode)) {
                    if (isColDragCell && (isCrossDrag || isPeerDrag || !params.level) && !(disabledMethod && disabledMethod(params))) {
                        triggerDrag = true;
                        $xeTable.handleCellDragMousedownEvent(evnt, params);
                    }
                }
                if (!triggerDrag && $xeTable.handleCellMousedownEvent) {
                    $xeTable.handleCellMousedownEvent(evnt, params);
                }
                $xeTable.focus();
                $xeTable.closeFilter();
                if ($xeTable.closeMenu) {
                    $xeTable.closeMenu();
                }
            },
            triggerCellMouseupEvent() {
                clearDragStatus();
            },
            /**
             * 行拖拽
             */
            handleRowDragDragstartEvent(evnt) {
                if (evnt.dataTransfer) {
                    evnt.dataTransfer.setDragImage(getTpImg(), 0, 0);
                }
                $xeTable.closeTooltip();
            },
            handleRowDragSwapEvent(evnt, isSyncRow, dragRow, prevDragRow, prevDragPos, prevDragToChild) {
                const { treeConfig, dragConfig } = props;
                const rowDragOpts = computeRowDragOpts.value;
                const { afterFullData, tableFullData, fullAllDataRowIdData } = internalData;
                const $xeGanttView = internalData.xeGanttView;
                const { animation, isPeerDrag, isCrossDrag, isSelfToChildDrag, dragEndMethod, dragToChildMethod } = rowDragOpts;
                const treeOpts = computeTreeOpts.value;
                const cellOpts = computeCellOpts.value;
                const rowOpts = computeRowOpts.value;
                const defaultRowHeight = computeDefaultRowHeight.value;
                const { transform, rowField, mapChildrenField, parentField } = treeOpts;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                const dEndMethod = dragEndMethod || (dragConfig ? dragConfig.dragEndMethod : null);
                const dragOffsetIndex = prevDragPos === 'bottom' ? 1 : 0;
                const el = refElem.value;
                const errRest = {
                    status: false
                };
                if (!(el && prevDragRow && dragRow)) {
                    handleRowDragEndClearStatus();
                    return Promise.resolve(errRest);
                }
                // 判断是否有拖动
                if (prevDragRow !== dragRow) {
                    const dragParams = {
                        oldRow: dragRow,
                        newRow: prevDragRow,
                        dragRow,
                        dragPos: prevDragPos,
                        dragToChild: !!prevDragToChild,
                        offsetIndex: dragOffsetIndex
                    };
                    const dragRowid = getRowid($xeTable, dragRow);
                    const dragRowRest = fullAllDataRowIdData[dragRowid] || {};
                    const _dragRowIndex = dragRowRest._index;
                    let dragRowHeight = 0;
                    let dragOffsetTop = -1;
                    if (animation) {
                        dragRowHeight = getCellRestHeight(dragRowRest, cellOpts, rowOpts, defaultRowHeight);
                        const oldTrEl = el.querySelector(`.vxe-body--row[rowid="${dragRowid}"]`);
                        if (oldTrEl) {
                            dragOffsetTop = oldTrEl.offsetTop;
                        }
                    }
                    let oafIndex = -1;
                    let nafIndex = -1;
                    const oldRest = dragRowRest;
                    const newRowid = getRowid($xeTable, prevDragRow);
                    const newRest = fullAllDataRowIdData[newRowid];
                    const oldAllMaps = {};
                    let isSelfToChildStatus = false;
                    // 如果为树结构
                    if (treeConfig) {
                        if (transform) {
                            if (oldRest && newRest) {
                                const { level: oldLevel } = oldRest;
                                const { level: newLevel } = newRest;
                                XEUtils.eachTree([dragRow], item => {
                                    oldAllMaps[getRowid($xeTable, item)] = item;
                                }, { children: mapChildrenField });
                                if (oldLevel && newLevel) {
                                    // 子到子
                                    if (isPeerDrag && !isCrossDrag) {
                                        if (oldRest.row[parentField] !== newRest.row[parentField]) {
                                            // 非同级
                                            handleRowDragEndClearStatus();
                                            return Promise.resolve(errRest);
                                        }
                                    }
                                    else {
                                        if (!isCrossDrag) {
                                            handleRowDragEndClearStatus();
                                            return Promise.resolve(errRest);
                                        }
                                        if (oldAllMaps[newRowid]) {
                                            isSelfToChildStatus = true;
                                            if (!(isCrossDrag && isSelfToChildDrag)) {
                                                if (VxeUI.modal) {
                                                    VxeUI.modal.message({
                                                        status: 'error',
                                                        content: getI18n('vxe.error.treeDragChild')
                                                    });
                                                }
                                                handleRowDragEndClearStatus();
                                                return Promise.resolve(errRest);
                                            }
                                        }
                                    }
                                }
                                else if (oldLevel) {
                                    // 子到根
                                    if (!isCrossDrag) {
                                        handleRowDragEndClearStatus();
                                        return Promise.resolve(errRest);
                                    }
                                }
                                else if (newLevel) {
                                    // 根到子
                                    if (!isCrossDrag) {
                                        handleRowDragEndClearStatus();
                                        return Promise.resolve(errRest);
                                    }
                                    if (oldAllMaps[newRowid]) {
                                        isSelfToChildStatus = true;
                                        if (!(isCrossDrag && isSelfToChildDrag)) {
                                            if (VxeUI.modal) {
                                                VxeUI.modal.message({
                                                    status: 'error',
                                                    content: getI18n('vxe.error.treeDragChild')
                                                });
                                            }
                                            handleRowDragEndClearStatus();
                                            return Promise.resolve(errRest);
                                        }
                                    }
                                }
                                else {
                                    // 根到根
                                }
                            }
                        }
                    }
                    const isDragToChildFlag = isSelfToChildDrag && dragToChildMethod ? dragToChildMethod(dragParams) : prevDragToChild;
                    if (dEndMethod) {
                        handleRowDragEndClearStatus();
                    }
                    return Promise.resolve(dEndMethod ? dEndMethod(dragParams) : true).then((status) => {
                        if (!status) {
                            return errRest;
                        }
                        // 如果为树结构
                        if (treeConfig) {
                            if (transform) {
                                // 移出源位置
                                if (oldRest && newRest) {
                                    const fullList = XEUtils.toTreeArray(internalData.afterTreeFullData, {
                                        updated: false,
                                        key: rowField,
                                        parentKey: parentField,
                                        children: mapChildrenField
                                    });
                                    // 移出
                                    const otfIndex = $xeTable.findRowIndexOf(fullList, dragRow);
                                    fullList.splice(otfIndex, 1);
                                    // 插入
                                    const ptfIndex = $xeTable.findRowIndexOf(fullList, prevDragRow);
                                    const ntfIndex = ptfIndex + dragOffsetIndex;
                                    fullList.splice(ntfIndex, 0, dragRow);
                                    // 改变层级
                                    if (isSelfToChildStatus && (isCrossDrag && isSelfToChildDrag)) {
                                        XEUtils.each(dragRow[childrenField], childRow => {
                                            childRow[parentField] = dragRow[parentField];
                                        });
                                    }
                                    dragRow[parentField] = isDragToChildFlag ? prevDragRow[rowField] : prevDragRow[parentField];
                                    internalData.tableFullTreeData = XEUtils.toArrayTree(fullList, {
                                        key: rowField,
                                        parentKey: parentField,
                                        children: childrenField,
                                        mapChildren: mapChildrenField
                                    });
                                }
                            }
                        }
                        else {
                            // 移出
                            oafIndex = $xeTable.findRowIndexOf(afterFullData, dragRow);
                            const otfIndex = $xeTable.findRowIndexOf(tableFullData, dragRow);
                            afterFullData.splice(oafIndex, 1);
                            tableFullData.splice(otfIndex, 1);
                            // 插入
                            const pafIndex = $xeTable.findRowIndexOf(afterFullData, prevDragRow);
                            const ptfIndex = $xeTable.findRowIndexOf(tableFullData, prevDragRow);
                            nafIndex = pafIndex + dragOffsetIndex;
                            const ntfIndex = ptfIndex + dragOffsetIndex;
                            afterFullData.splice(nafIndex, 0, dragRow);
                            tableFullData.splice(ntfIndex, 0, dragRow);
                        }
                        $xeTable.handleClearStack();
                        $xeTable.handleTableData(treeConfig && transform);
                        $xeTable.cacheRowMap(false);
                        updateScrollYStatus();
                        if (!(treeConfig && transform)) {
                            $xeTable.updateAfterDataIndex();
                        }
                        $xeTable.checkSelectionStatus();
                        if (reactData.scrollYLoad) {
                            $xeTable.updateScrollYSpace();
                        }
                        if (evnt) {
                            dispatchEvent('row-dragend', {
                                oldRow: dragRow,
                                newRow: prevDragRow,
                                dragRow,
                                dragPos: prevDragPos,
                                dragToChild: isDragToChildFlag,
                                offsetIndex: dragOffsetIndex,
                                _index: {
                                    newIndex: nafIndex,
                                    oldIndex: oafIndex
                                }
                            }, evnt);
                        }
                        return nextTick().then(() => {
                            if (animation) {
                                const { tableData } = reactData;
                                const { fullAllDataRowIdData } = internalData;
                                const dragRowRest = fullAllDataRowIdData[dragRowid];
                                const _newRowIndex = dragRowRest._index;
                                const firstRow = tableData[0];
                                const firstRowRest = fullAllDataRowIdData[getRowid($xeTable, firstRow)];
                                let wrapperEl = el;
                                if ($xeGantt && $xeGanttView) {
                                    const { refGanttContainerElem } = $xeGantt.getRefMaps();
                                    const ganttContainerElem = refGanttContainerElem.value;
                                    if (ganttContainerElem) {
                                        wrapperEl = ganttContainerElem;
                                    }
                                }
                                if (firstRowRest) {
                                    const _firstRowIndex = firstRowRest._index;
                                    const _lastRowIndex = _firstRowIndex + tableData.length;
                                    let rsIndex = -1;
                                    let reIndex = -1;
                                    let offsetRate = 1;
                                    if (_dragRowIndex < _firstRowIndex) {
                                        // 从上往下虚拟拖拽
                                        rsIndex = 0;
                                        reIndex = _newRowIndex - _firstRowIndex;
                                    }
                                    else if (_dragRowIndex > _lastRowIndex) {
                                        // 从下往上虚拟拖拽
                                        const $newRowIndex = dragRowRest.$index;
                                        rsIndex = $newRowIndex + 1;
                                        reIndex = tableData.length;
                                        offsetRate = -1;
                                    }
                                    else {
                                        if (_newRowIndex > _dragRowIndex) {
                                            // 从上往下拖拽
                                            rsIndex = _dragRowIndex - _firstRowIndex;
                                            reIndex = rsIndex + _newRowIndex - _dragRowIndex;
                                        }
                                        else {
                                            // 从下往上拖拽
                                            rsIndex = _newRowIndex - _firstRowIndex;
                                            reIndex = rsIndex + _dragRowIndex - _newRowIndex + 1;
                                            offsetRate = -1;
                                        }
                                    }
                                    const dragRangeList = tableData.slice(rsIndex, reIndex);
                                    if (dragRangeList.length) {
                                        const dtClss = [];
                                        dragRangeList.forEach(row => {
                                            const rowid = getRowid($xeTable, row);
                                            dtClss.push(`.vxe-body--row[rowid="${rowid}"]`);
                                            if ($xeGantt) {
                                                dtClss.push(`.vxe-gantt-view--body-row[rowid="${rowid}"]`, `.vxe-gantt-view--chart-row[rowid="${rowid}"]`);
                                            }
                                        });
                                        const dtTrList = wrapperEl.querySelectorAll(dtClss.join(','));
                                        moveRowAnimateToTb(dtTrList, offsetRate * dragRowHeight);
                                    }
                                }
                                const drClss = [`.vxe-body--row[rowid="${dragRowid}"]`];
                                if ($xeGantt) {
                                    drClss.push(`.vxe-gantt-view--body-row[rowid="${dragRowid}"]`, `.vxe-gantt-view--chart-row[rowid="${dragRowid}"]`);
                                }
                                const newDtTrList = wrapperEl.querySelectorAll(drClss.join(','));
                                const newTrEl = newDtTrList[0];
                                if (dragOffsetTop > -1 && newTrEl) {
                                    moveRowAnimateToTb(newDtTrList, dragOffsetTop - newTrEl.offsetTop);
                                }
                            }
                            updateRowOffsetTop();
                            updateRowExpandStyle();
                            $xeTable.updateCellAreas();
                            $xeTable.recalculate();
                        }).then(() => {
                            return {
                                status: true
                            };
                        });
                    }).catch(() => {
                        return errRest;
                    }).then((rest) => {
                        handleRowDragEndClearStatus();
                        return rest;
                    });
                }
                handleRowDragEndClearStatus();
                return Promise.resolve(errRest);
            },
            handleCrossTableRowDragCancelEvent() {
                handleRowDragEndClearStatus();
            },
            /**
             * 处理跨表拖拽完成
             */
            handleCrossTableRowDragFinishEvent(evnt) {
                const { tableData } = reactData;
                const { fullAllDataRowIdData } = internalData;
                const rowOpts = computeRowOpts.value;
                const cellOpts = computeCellOpts.value;
                const defaultRowHeight = computeDefaultRowHeight.value;
                const rowDragOpts = computeRowDragOpts.value;
                const { animation, isCrossTableDrag } = rowDragOpts;
                const treeOpts = computeTreeOpts.value;
                const { mapChildrenField } = treeOpts;
                const el = refElem.value;
                if (isCrossTableDrag && crossTableDragRowObj && crossTableDragRowInfo) {
                    const { row: dragRow } = crossTableDragRowInfo;
                    if (dragRow) {
                        const dragRowid = getRowid($xeTable, dragRow);
                        const dragRowRest = fullAllDataRowIdData[dragRowid];
                        let dragRowHeight = 0;
                        let rsIndex = -1;
                        if (dragRowRest) {
                            if (animation) {
                                dragRowHeight = getCellRestHeight(dragRowRest, cellOpts, rowOpts, defaultRowHeight);
                            }
                            rsIndex = dragRowRest.$index;
                        }
                        const dragRangeList = rsIndex > -1 && rsIndex < tableData.length - 1 ? tableData.slice(rsIndex + 1) : [];
                        const dragList = XEUtils.toTreeArray([dragRow], {
                            updated: true,
                            children: mapChildrenField
                        });
                        $xeTable.remove(dragList).then(() => {
                            if (animation && dragRowHeight && dragRangeList.length) {
                                const $xeGanttView = internalData.xeGanttView;
                                let wrapperEl = el;
                                if ($xeGantt && $xeGanttView) {
                                    const { refGanttContainerElem } = $xeGantt.getRefMaps();
                                    const ganttContainerElem = refGanttContainerElem.value;
                                    if (ganttContainerElem) {
                                        wrapperEl = ganttContainerElem;
                                    }
                                }
                                const dtClss = [];
                                dragRangeList.forEach(row => {
                                    const rowid = getRowid($xeTable, row);
                                    dtClss.push(`.vxe-body--row[rowid="${rowid}"]`);
                                    if ($xeGantt) {
                                        dtClss.push(`.vxe-gantt-view--body-row[rowid="${rowid}"]`, `.vxe-gantt-view--chart-row[rowid="${rowid}"]`);
                                    }
                                });
                                const dtTrList = wrapperEl.querySelectorAll(dtClss.join(','));
                                moveRowAnimateToTb(dtTrList, dragRowHeight);
                            }
                        });
                        dispatchEvent('row-remove-dragend', {
                            row: dragRow
                        }, evnt);
                        handleRowDragEndClearStatus();
                    }
                }
            },
            /**
             * 处理跨表拖至新的空表
             */
            handleCrossTableRowDragoverEmptyEvent(evnt) {
                const { tableData } = reactData;
                const rowDragOpts = computeRowDragOpts.value;
                const { isCrossTableDrag } = rowDragOpts;
                if (isCrossTableDrag && crossTableDragRowObj && !tableData.length) {
                    const { $oldTable, $newTable } = crossTableDragRowObj;
                    if ($oldTable) {
                        const oldTableReactData = $oldTable.reactData;
                        if ($oldTable.xID !== $xeTable.xID) {
                            if ($newTable && $newTable.xID !== $xeTable.xID) {
                                $newTable.hideCrossTableRowDropClearStatus();
                            }
                            evnt.preventDefault();
                            $oldTable.hideCrossTableRowDropClearStatus();
                            crossTableDragRowObj.$newTable = $xeTable;
                            internalData.prevDragRow = null;
                            reactData.dragTipText = oldTableReactData.dragTipText;
                            showDropTip(evnt, evnt.currentTarget, null, true, '');
                        }
                    }
                }
            },
            /**
             * 处理跨表拖插入
             */
            handleCrossTableRowDragInsertEvent(evnt) {
                const { treeConfig } = props;
                const { prevDragRow, prevDragPos, prevDragToChild } = internalData;
                const rowDragOpts = computeRowDragOpts.value;
                const { animation, isSelfToChildDrag, isCrossTableDrag, dragEndMethod, dragToChildMethod } = rowDragOpts;
                const rowOpts = computeRowOpts.value;
                const cellOpts = computeCellOpts.value;
                const defaultRowHeight = computeDefaultRowHeight.value;
                const treeOpts = computeTreeOpts.value;
                const { parentField, mapChildrenField } = treeOpts;
                const childrenField = treeOpts.children || treeOpts.childrenField;
                // 跨表拖拽
                if (isCrossTableDrag && crossTableDragRowObj && crossTableDragRowInfo) {
                    const { row: oldRow } = crossTableDragRowInfo;
                    const { $oldTable } = crossTableDragRowObj;
                    const el = refElem.value;
                    if ($oldTable && oldRow) {
                        const dragRow = oldRow;
                        let dragOffsetIndex = -1;
                        if (prevDragRow) {
                            dragOffsetIndex = prevDragPos === 'bottom' ? 1 : 0;
                        }
                        const dragParams = {
                            oldRow: dragRow,
                            newRow: prevDragRow,
                            dragRow,
                            dragPos: prevDragPos,
                            dragToChild: !!prevDragToChild,
                            offsetIndex: dragOffsetIndex
                        };
                        const isDragToChildFlag = isSelfToChildDrag && dragToChildMethod ? dragToChildMethod(dragParams) : prevDragToChild;
                        const errRest = {
                            status: false
                        };
                        if (dragEndMethod) {
                            handleRowDragEndClearStatus();
                        }
                        Promise.resolve(dragEndMethod ? dragEndMethod(dragParams) : true).then((status) => {
                            if (!status) {
                                if ($oldTable) {
                                    if ($oldTable.xID !== $xeTable.xID) {
                                        $oldTable.handleCrossTableRowDragCancelEvent(evnt);
                                    }
                                }
                                handleRowDragEndClearStatus();
                                return errRest;
                            }
                            let insertRest = Promise.resolve();
                            if (treeConfig) {
                                const dragList = XEUtils.toTreeArray([dragRow], {
                                    updated: true,
                                    children: mapChildrenField
                                });
                                $oldTable.handleCrossTableRowDragFinishEvent(evnt);
                                if (prevDragRow) {
                                    dragRow[parentField] = prevDragRow[parentField];
                                }
                                else {
                                    dragRow[parentField] = null;
                                }
                                dragList.forEach(row => {
                                    row[childrenField] = undefined;
                                    row[mapChildrenField] = undefined;
                                });
                                if (prevDragRow) {
                                    if (prevDragPos === 'bottom') {
                                        insertRest = $xeTable.insertNextAt(dragList, prevDragRow);
                                    }
                                    else {
                                        insertRest = $xeTable.insertAt(dragList, prevDragRow);
                                    }
                                }
                                else {
                                    insertRest = $xeTable.insert(dragList);
                                }
                            }
                            else {
                                $oldTable.handleCrossTableRowDragFinishEvent(evnt);
                                if (prevDragRow) {
                                    if (prevDragPos === 'bottom') {
                                        insertRest = $xeTable.insertNextAt(dragRow, prevDragRow);
                                    }
                                    else {
                                        insertRest = $xeTable.insertAt(dragRow, prevDragRow);
                                    }
                                }
                                else {
                                    insertRest = $xeTable.insert(dragRow);
                                }
                            }
                            dispatchEvent('row-insert-dragend', {
                                oldRow,
                                newRow: prevDragRow,
                                dragRow,
                                dragPos: prevDragPos,
                                dragToChild: isDragToChildFlag,
                                offsetIndex: dragOffsetIndex
                            }, evnt);
                            clearRowDragData();
                            insertRest.then(() => {
                                const { tableData } = reactData;
                                const { fullAllDataRowIdData } = internalData;
                                const oldRowid = getRowid($xeTable, dragRow);
                                const oldRowRest = fullAllDataRowIdData[oldRowid];
                                let dragRowHeight = 0;
                                let rsIndex = -1;
                                if (oldRowRest) {
                                    if (animation) {
                                        dragRowHeight = getCellRestHeight(oldRowRest, cellOpts, rowOpts, defaultRowHeight);
                                    }
                                    rsIndex = oldRowRest.$index;
                                }
                                const dragRangeList = rsIndex > -1 ? tableData.slice(rsIndex) : [];
                                if (animation && dragRowHeight && dragRangeList.length) {
                                    const $xeGanttView = internalData.xeGanttView;
                                    let wrapperEl = el;
                                    if ($xeGantt && $xeGanttView) {
                                        const { refGanttContainerElem } = $xeGantt.getRefMaps();
                                        const ganttContainerElem = refGanttContainerElem.value;
                                        if (ganttContainerElem) {
                                            wrapperEl = ganttContainerElem;
                                        }
                                    }
                                    const dtClss = [];
                                    dragRangeList.forEach(row => {
                                        const rowid = getRowid($xeTable, row);
                                        dtClss.push(`.vxe-body--row[rowid="${rowid}"]`);
                                        if ($xeGantt) {
                                            dtClss.push(`.vxe-gantt-view--body-row[rowid="${rowid}"]`, `.vxe-gantt-view--chart-row[rowid="${rowid}"]`);
                                        }
                                    });
                                    const dtTrList = wrapperEl.querySelectorAll(dtClss.join(','));
                                    moveRowAnimateToTb(dtTrList, -dragRowHeight);
                                }
                            });
                        });
                    }
                }
            },
            hideCrossTableRowDropClearStatus() {
                hideDropTip();
            },
            handleRowDragDragendEvent(evnt) {
                const { treeConfig } = props;
                const { fullAllDataRowIdData, prevDragToChild } = internalData;
                const { dragRow } = reactData;
                const treeOpts = computeTreeOpts.value;
                const { lazy } = treeOpts;
                const hasChildField = treeOpts.hasChild || treeOpts.hasChildField;
                const { prevDragRow, prevDragPos } = internalData;
                const rowDragOpts = computeRowDragOpts.value;
                const { isCrossTableDrag } = rowDragOpts;
                // 跨表拖拽
                if (isCrossTableDrag && crossTableDragRowObj) {
                    const { $newTable } = crossTableDragRowObj;
                    if ($newTable && $newTable.xID !== $xeTable.xID) {
                        $newTable.handleCrossTableRowDragInsertEvent(evnt);
                        return;
                    }
                }
                if (treeConfig && lazy && prevDragToChild) {
                    // 懒加载
                    const newRowid = getRowid($xeTable, prevDragRow);
                    const rowRest = fullAllDataRowIdData[newRowid];
                    if (prevDragRow[hasChildField]) {
                        if (rowRest && rowRest.treeLoaded) {
                            $xeTable.handleRowDragSwapEvent(evnt, true, dragRow, prevDragRow, prevDragPos, prevDragToChild);
                        }
                    }
                    else {
                        $xeTable.handleRowDragSwapEvent(evnt, true, dragRow, prevDragRow, prevDragPos, prevDragToChild);
                    }
                }
                else {
                    $xeTable.handleRowDragSwapEvent(evnt, true, dragRow, prevDragRow, prevDragPos, prevDragToChild);
                }
            },
            handleRowDragDragoverEvent(evnt) {
                const { treeConfig } = props;
                const { fullAllDataRowIdData } = internalData;
                const { dragRow } = reactData;
                const treeOpts = computeTreeOpts.value;
                const { lazy, transform, parentField } = treeOpts;
                const hasChildField = treeOpts.hasChild || treeOpts.hasChildField;
                const rowDragOpts = computeRowDragOpts.value;
                const { isPeerDrag, isCrossDrag, isToChildDrag, isCrossTableDrag } = rowDragOpts;
                if (!dragRow && !(isCrossTableDrag && (!treeConfig || isCrossDrag) && crossTableDragRowObj)) {
                    evnt.preventDefault();
                    return;
                }
                const isControlKey = hasControlKey(evnt);
                const trEl = evnt.currentTarget;
                const rowid = trEl.getAttribute('rowid') || '';
                const rowRest = fullAllDataRowIdData[rowid];
                if (rowRest) {
                    evnt.preventDefault();
                    const row = rowRest.row;
                    const offsetY = evnt.clientY - trEl.getBoundingClientRect().y;
                    const dragPos = offsetY < trEl.clientHeight / 2 ? 'top' : 'bottom';
                    internalData.prevDragToChild = !!(treeConfig && transform && (isCrossDrag && isToChildDrag) && isControlKey);
                    internalData.prevDragRow = row;
                    internalData.prevDragPos = dragPos;
                    // 跨表拖拽
                    if (isCrossTableDrag && (!treeConfig || isCrossDrag) && crossTableDragRowObj) {
                        const { $oldTable, $newTable } = crossTableDragRowObj;
                        if ($oldTable) {
                            const oldTableReactData = $oldTable.reactData;
                            if ($oldTable.xID === $xeTable.xID) {
                                if ($newTable) {
                                    $newTable.hideCrossTableRowDropClearStatus();
                                }
                                reactData.isCrossDragRow = false;
                                oldTableReactData.isCrossDragRow = false;
                                crossTableDragRowObj.$newTable = null;
                            }
                            else {
                                if ($newTable && $newTable.xID !== $xeTable.xID) {
                                    $newTable.hideCrossTableRowDropClearStatus();
                                }
                                $oldTable.hideCrossTableRowDropClearStatus();
                                oldTableReactData.isCrossDragRow = true;
                                reactData.dragTipText = oldTableReactData.dragTipText;
                                crossTableDragRowObj.$newTable = $xeTable;
                                showDropTip(evnt, trEl, null, true, dragPos);
                                return;
                            }
                        }
                    }
                    if ($xeTable.eqRow(dragRow, row) ||
                        (isControlKey && treeConfig && lazy && row[hasChildField] && rowRest && !rowRest.treeLoaded) ||
                        (!isCrossDrag && treeConfig && transform && (isPeerDrag ? dragRow[parentField] !== row[parentField] : rowRest.level))) {
                        showDropTip(evnt, trEl, null, false, dragPos);
                        return;
                    }
                    showDropTip(evnt, trEl, null, true, dragPos);
                    dispatchEvent('row-dragover', {
                        oldRow: dragRow,
                        targetRow: row,
                        dragPos
                    }, evnt);
                }
            },
            handleCellDragMousedownEvent(evnt, params) {
                var _a;
                evnt.stopPropagation();
                const { dragConfig } = props;
                const rowDragOpts = computeRowDragOpts.value;
                const { isCrossTableDrag, trigger, dragStartMethod } = rowDragOpts;
                const { row } = params;
                const dragEl = evnt.currentTarget;
                const tdEl = trigger === 'cell' || trigger === 'row' ? dragEl : (_a = dragEl.parentElement) === null || _a === void 0 ? void 0 : _a.parentElement;
                const trEl = tdEl.parentElement;
                const dStartMethod = dragStartMethod || (dragConfig ? dragConfig.dragStartMethod : null);
                clearRowDropOrigin();
                if (dStartMethod && !dStartMethod(params)) {
                    trEl.draggable = false;
                    reactData.dragRow = null;
                    reactData.dragCol = null;
                    clearCrossTableDragStatus();
                    hideDropTip();
                    return;
                }
                if (isCrossTableDrag) {
                    crossTableDragRowInfo.row = row;
                    crossTableDragRowObj = { $oldTable: $xeTable, $newTable: null };
                }
                reactData.dragRow = row;
                reactData.isCrossDragRow = false;
                reactData.dragCol = null;
                trEl.draggable = true;
                updateRowDropOrigin(row);
                updateRowDropTipContent(tdEl);
                dispatchEvent('row-dragstart', params, evnt);
            },
            handleCellDragMouseupEvent() {
                clearDragStatus();
            },
            /**
             * 列拖拽
             */
            handleHeaderCellDragDragstartEvent(evnt) {
                if (evnt.dataTransfer) {
                    evnt.dataTransfer.setDragImage(getTpImg(), 0, 0);
                }
                $xeTable.closeTooltip();
            },
            handleColDragSwapColumn() {
                handleUpdateColumn();
                return parseColumns(false).then(() => {
                    $xeTable.updateCellAreas();
                    $xeTable.saveCustomStore('update:sort');
                });
            },
            handleColDragSwapEvent(evnt, isSyncColumn, dragCol, prevDragCol, prevDragPos, prevDragToChild) {
                const { mouseConfig } = props;
                const columnDragOpts = computeColumnDragOpts.value;
                const { animation, isPeerDrag, isCrossDrag, isSelfToChildDrag, isToChildDrag, dragEndMethod, dragToChildMethod } = columnDragOpts;
                const { collectColumn, fullColumnIdData } = internalData;
                const el = refElem.value;
                const dragOffsetIndex = prevDragPos === 'right' ? 1 : 0;
                const errRest = {
                    status: false
                };
                if (!(el && prevDragCol && dragCol)) {
                    return Promise.resolve(errRest);
                }
                // 判断是否有拖动
                if (prevDragCol !== dragCol) {
                    const dragColumn = dragCol;
                    const newColumn = prevDragCol;
                    const dragParams = {
                        oldColumn: dragColumn,
                        newColumn,
                        dragColumn,
                        dragPos: prevDragPos,
                        dragToChild: !!prevDragToChild,
                        offsetIndex: dragOffsetIndex
                    };
                    let dragTargetColumn = null;
                    const dragAllTargetCols = [];
                    let dragColWidth = 0;
                    if (animation) {
                        XEUtils.eachTree([dragColumn], column => {
                            if (!dragTargetColumn && (!column.children || !column.children.length)) {
                                dragTargetColumn = column;
                                dragColWidth += column.renderWidth;
                            }
                            dragAllTargetCols.push(column);
                        });
                    }
                    if (!dragTargetColumn) {
                        dragTargetColumn = dragColumn;
                    }
                    const dragColRest = fullColumnIdData[dragTargetColumn.id] || {};
                    const _dragColIndex = dragColRest._index;
                    let dragOffsetLeft = -1;
                    if (animation) {
                        const oldTrEl = el.querySelector(`.vxe-table--column[colid="${dragTargetColumn.id}"]`);
                        if (oldTrEl) {
                            dragOffsetLeft = oldTrEl.offsetLeft;
                        }
                    }
                    let oafIndex = -1;
                    let nafIndex = -1;
                    const oldAllMaps = {};
                    XEUtils.eachTree([dragColumn], column => {
                        oldAllMaps[column.id] = column;
                    });
                    let isSelfToChildStatus = false;
                    if (dragColumn.parentId && newColumn.parentId) {
                        // 子到子
                        if (isPeerDrag && !isCrossDrag) {
                            if (dragColumn.parentId !== newColumn.parentId) {
                                // 非同级
                                handleColDragEndClearStatus();
                                return Promise.resolve(errRest);
                            }
                        }
                        else {
                            if (!isCrossDrag) {
                                handleColDragEndClearStatus();
                                return Promise.resolve(errRest);
                            }
                            if (oldAllMaps[newColumn.id]) {
                                isSelfToChildStatus = true;
                                if (!(isCrossDrag && isSelfToChildDrag)) {
                                    if (VxeUI.modal) {
                                        VxeUI.modal.message({
                                            status: 'error',
                                            content: getI18n('vxe.error.treeDragChild')
                                        });
                                    }
                                    handleColDragEndClearStatus();
                                    return Promise.resolve(errRest);
                                }
                            }
                        }
                    }
                    else if (dragColumn.parentId) {
                        // 子到根
                        if (!isCrossDrag) {
                            handleColDragEndClearStatus();
                            return Promise.resolve(errRest);
                        }
                    }
                    else if (newColumn.parentId) {
                        // 根到子
                        if (!isCrossDrag) {
                            handleColDragEndClearStatus();
                            return Promise.resolve(errRest);
                        }
                        if (oldAllMaps[newColumn.id]) {
                            isSelfToChildStatus = true;
                            if (!(isCrossDrag && isSelfToChildDrag)) {
                                if (VxeUI.modal) {
                                    VxeUI.modal.message({
                                        status: 'error',
                                        content: getI18n('vxe.error.treeDragChild')
                                    });
                                }
                                handleColDragEndClearStatus();
                                return Promise.resolve(errRest);
                            }
                        }
                    }
                    else {
                        // 根到根
                    }
                    const isDragToChildFlag = isSelfToChildDrag && dragToChildMethod ? dragToChildMethod(dragParams) : prevDragToChild;
                    return Promise.resolve(dragEndMethod ? dragEndMethod(dragParams) : true).then((status) => {
                        if (!status) {
                            return errRest;
                        }
                        const oldewMatchRest = XEUtils.findTree(collectColumn, item => item.id === dragColumn.id);
                        // 改变层级
                        if (isSelfToChildStatus && (isCrossDrag && isSelfToChildDrag)) {
                            if (oldewMatchRest) {
                                const { items: oCols, index: oIndex } = oldewMatchRest;
                                const childList = dragColumn.children || [];
                                childList.forEach(column => {
                                    column.parentId = dragColumn.parentId;
                                });
                                oCols.splice(oIndex, 1, ...childList);
                                dragColumn.children = [];
                            }
                        }
                        else {
                            if (oldewMatchRest) {
                                const { items: oCols, index: oIndex, parent: oParent } = oldewMatchRest;
                                oCols.splice(oIndex, 1);
                                if (!oParent) {
                                    oafIndex = oIndex;
                                }
                            }
                        }
                        const newMatchRest = XEUtils.findTree(collectColumn, item => item.id === newColumn.id);
                        if (newMatchRest) {
                            const { items: nCols, index: nIndex, parent: nParent } = newMatchRest;
                            // 转子级
                            if ((isCrossDrag && isToChildDrag) && isDragToChildFlag) {
                                dragColumn.parentId = newColumn.id;
                                newColumn.children = (newColumn.children || []).concat([dragColumn]);
                            }
                            else {
                                dragColumn.parentId = newColumn.parentId;
                                nCols.splice(nIndex + dragOffsetIndex, 0, dragColumn);
                            }
                            if (!nParent) {
                                nafIndex = nIndex;
                            }
                        }
                        XEUtils.eachTree(collectColumn, (column, index, items, path, parentColumn) => {
                            if (!parentColumn) {
                                const sortIndex = index + 1;
                                column.renderSortNumber = sortIndex;
                            }
                        });
                        $xeTable.handleClearStack();
                        if (mouseConfig) {
                            if ($xeTable.clearSelected) {
                                $xeTable.clearSelected();
                            }
                            if ($xeTable.clearCellAreas) {
                                $xeTable.clearCellAreas();
                                $xeTable.clearCopyCellArea();
                            }
                        }
                        if (evnt) {
                            dispatchEvent('column-dragend', {
                                oldColumn: dragColumn,
                                newColumn,
                                dragColumn,
                                dragPos: prevDragPos,
                                dragToChild: isDragToChildFlag,
                                offsetIndex: dragOffsetIndex,
                                _index: {
                                    newIndex: nafIndex,
                                    oldIndex: oafIndex
                                }
                            }, evnt);
                        }
                        return nextTick().then(() => {
                            if (isSyncColumn) {
                                return $xeTable.handleColDragSwapColumn();
                            }
                        }).then(() => {
                            if (animation) {
                                const { tableColumn } = reactData;
                                const { visibleColumn, fullColumnIdData } = internalData;
                                let dragNewColumn = null;
                                const dragNewColMaps = {};
                                XEUtils.eachTree([dragColumn], column => {
                                    if (!dragNewColumn && (!column.children || !column.children.length)) {
                                        dragNewColumn = column;
                                    }
                                    dragNewColMaps[column.id] = column;
                                });
                                if (!dragNewColumn) {
                                    dragNewColumn = dragColumn;
                                }
                                if (dragColWidth && dragAllTargetCols.length) {
                                    const _newColIndex = XEUtils.findIndexOf(visibleColumn, column => !!dragNewColumn && column.id === dragNewColumn.id);
                                    const firstCol = tableColumn[0];
                                    const firstColRest = fullColumnIdData[firstCol.id];
                                    if (firstColRest) {
                                        const _firstColIndex = firstColRest._index;
                                        const _lastColIndex = _firstColIndex + tableColumn.length;
                                        let csIndex = -1;
                                        let ceIndex = -1;
                                        let offsetRate = 1;
                                        if (_dragColIndex < _firstColIndex) {
                                            // 从左往右虚拟拖拽
                                            csIndex = 0;
                                            ceIndex = _newColIndex - _firstColIndex;
                                        }
                                        else if (_dragColIndex > _lastColIndex) {
                                            // 从右往左虚拟拖拽
                                            const $newRowIndex = dragColRest.$index;
                                            csIndex = $newRowIndex + 1;
                                            ceIndex = tableColumn.length;
                                            offsetRate = -1;
                                        }
                                        else {
                                            if (_newColIndex > _dragColIndex) {
                                                // 从左往右拖拽
                                                csIndex = _dragColIndex - _firstColIndex;
                                                ceIndex = csIndex + _newColIndex - _dragColIndex;
                                            }
                                            else {
                                                // 从右往左拖拽
                                                csIndex = _newColIndex - _firstColIndex + 1;
                                                ceIndex = csIndex + _dragColIndex - _newColIndex;
                                                offsetRate = -1;
                                            }
                                        }
                                        const dragRangeList = [];
                                        const dragRangeMaps = {};
                                        for (let i = csIndex; i < ceIndex; i++) {
                                            const column = tableColumn[i];
                                            if (!dragRangeMaps[column.id] && !dragNewColMaps[column.id]) {
                                                dragRangeMaps[column.id] = column;
                                                dragRangeList.push(column);
                                            }
                                        }
                                        XEUtils.eachTree([newColumn], column => {
                                            if (!dragRangeMaps[column.id]) {
                                                dragRangeMaps[column.id] = column;
                                                dragRangeList.push(column);
                                            }
                                        });
                                        if (dragRangeList.length) {
                                            const dtTrList = el.querySelectorAll(dragRangeList.map(column => `.vxe-table--column[colid="${column.id}"]`).join(','));
                                            moveColAnimateToLr(dtTrList, offsetRate * dragColWidth);
                                        }
                                    }
                                    const newTrList = el.querySelectorAll(dragAllTargetCols.map(column => `.vxe-table--column[colid="${column.id}"]`).join(','));
                                    const newTdEl = newTrList[0];
                                    if (dragOffsetLeft > -1 && newTdEl) {
                                        moveColAnimateToLr(newTrList, dragOffsetLeft - newTdEl.offsetLeft);
                                    }
                                }
                            }
                            updateColumnOffsetLeft();
                            loadScrollXData();
                            $xeTable.updateCellAreas();
                            return {
                                status: true
                            };
                        });
                    }).catch(() => {
                        return errRest;
                    }).then((rest) => {
                        handleColDragEndClearStatus();
                        return rest;
                    });
                }
                handleColDragEndClearStatus();
                return Promise.resolve(errRest);
            },
            handleHeaderCellDragDragendEvent(evnt) {
                const { dragCol } = reactData;
                const { prevDragCol, prevDragPos, prevDragToChild } = internalData;
                $xeTable.handleColDragSwapEvent(evnt, true, dragCol, prevDragCol, prevDragPos, prevDragToChild);
            },
            handleHeaderCellDragDragoverEvent(evnt) {
                const { dragCol } = reactData;
                const columnDragOpts = computeColumnDragOpts.value;
                const { isToChildDrag, isPeerDrag, isCrossDrag } = columnDragOpts;
                if (!dragCol) {
                    evnt.preventDefault();
                    return;
                }
                const isControlKey = hasControlKey(evnt);
                const thEl = evnt.currentTarget;
                const colid = thEl.getAttribute('colid');
                const column = $xeTable.getColumnById(colid);
                if (column) {
                    evnt.preventDefault();
                    const { clientX } = evnt;
                    const offsetX = clientX - thEl.getBoundingClientRect().x;
                    const dragPos = offsetX < thEl.clientWidth / 2 ? 'left' : 'right';
                    internalData.prevDragToChild = !!((isCrossDrag && isToChildDrag) && isControlKey);
                    internalData.prevDragCol = column;
                    internalData.prevDragPos = dragPos;
                    if (column.fixed ||
                        (dragCol && dragCol.id === column.id) ||
                        (!isCrossDrag && (isPeerDrag ? dragCol.parentId !== column.parentId : column.parentId))) {
                        showDropTip(evnt, null, thEl, false, dragPos);
                        return;
                    }
                    showDropTip(evnt, null, thEl, true, dragPos);
                    dispatchEvent('column-dragover', {
                        oldColumn: dragCol,
                        targetColumn: column,
                        dragPos
                    }, evnt);
                    // 边缘滚动
                    const el = refElem.value;
                    if (!el) {
                        return;
                    }
                    const xHandleEl = refScrollXHandleElem.value;
                    const tableBody = refTableBody.value;
                    const tableBodyElem = tableBody ? tableBody.$el : null;
                    const scrollTargetEl = xHandleEl || tableBodyElem;
                    if (scrollTargetEl) {
                        const wrapperRect = el.getBoundingClientRect();
                        const tableWrapperWidth = el.clientWidth;
                        const leftContainerElem = refLeftContainer.value;
                        const leftContainerWidth = leftContainerElem ? leftContainerElem.clientWidth : 0;
                        const rightContainerElem = refRightContainer.value;
                        const rightContainerWidth = rightContainerElem ? rightContainerElem.clientWidth : 0;
                        const srartX = wrapperRect.x + leftContainerWidth;
                        const endX = wrapperRect.x + tableWrapperWidth - rightContainerWidth;
                        const distSize = 28;
                        const startDistSize = clientX - srartX;
                        const endDistSize = endX - clientX;
                        if (startDistSize > 0 && startDistSize <= distSize) {
                            const scrollRatio = Math.floor(tableWrapperWidth / (startDistSize > distSize / 2 ? 240 : 120));
                            scrollTargetEl.scrollLeft -= scrollRatio * (distSize - startDistSize);
                        }
                        else if (endDistSize > 0 && endDistSize <= distSize) {
                            const scrollRatio = Math.floor(tableWrapperWidth / (endDistSize > distSize / 2 ? 240 : 120));
                            scrollTargetEl.scrollLeft += scrollRatio * (distSize - endDistSize);
                        }
                    }
                }
            },
            handleHeaderCellDragMousedownEvent(evnt, params) {
                var _a;
                evnt.stopPropagation();
                const columnDragOpts = computeColumnDragOpts.value;
                const { trigger, dragStartMethod } = columnDragOpts;
                const { column } = params;
                const dragEl = evnt.currentTarget;
                const thEl = trigger === 'cell' ? dragEl : (_a = dragEl.parentElement) === null || _a === void 0 ? void 0 : _a.parentElement;
                clearColDropOrigin();
                if (dragStartMethod && !dragStartMethod(params)) {
                    thEl.draggable = false;
                    reactData.dragRow = null;
                    reactData.dragCol = null;
                    clearCrossTableDragStatus();
                    hideDropTip();
                    return;
                }
                reactData.dragCol = column;
                reactData.dragRow = null;
                thEl.draggable = true;
                clearCrossTableDragStatus();
                updateColDropOrigin(column);
                updateColDropTipContent(thEl);
                dispatchEvent('column-dragstart', params, evnt);
            },
            handleHeaderCellDragMouseupEvent() {
                clearColDropOrigin();
                hideDropTip();
                clearCrossTableDragStatus();
                reactData.dragRow = null;
                reactData.dragCol = null;
            },
            handleScrollEvent(evnt, isRollY, isRollX, scrollTop, scrollLeft, params) {
                const { highlightHoverRow } = props;
                const { lastScrollLeft, lastScrollTop } = internalData;
                const xHandleEl = refScrollXHandleElem.value;
                const yHandleEl = refScrollYHandleElem.value;
                if (!xHandleEl || !yHandleEl) {
                    return;
                }
                const rowOpts = computeRowOpts.value;
                const validTip = refValidTooltip.value;
                const tooltip = refTooltip.value;
                const bodyHeight = yHandleEl.clientHeight;
                const bodyWidth = xHandleEl.clientWidth;
                const scrollHeight = yHandleEl.scrollHeight;
                const scrollWidth = xHandleEl.scrollWidth;
                let isTop = false;
                let isBottom = false;
                let isLeft = false;
                let isRight = false;
                let direction = '';
                let isTopBoundary = false;
                let isBottomBoundary = false;
                let isLeftBoundary = false;
                let isRightBoundary = false;
                if (isRollX) {
                    const xThreshold = computeScrollXThreshold.value;
                    isLeft = scrollLeft <= 0;
                    if (!isLeft) {
                        isRight = scrollLeft + bodyWidth >= scrollWidth;
                    }
                    if (scrollLeft > lastScrollLeft) {
                        direction = 'right';
                        if (scrollLeft + bodyWidth >= scrollWidth - xThreshold) {
                            isRightBoundary = true;
                        }
                    }
                    else {
                        direction = 'left';
                        if (scrollLeft <= xThreshold) {
                            isLeftBoundary = true;
                        }
                    }
                    $xeTable.checkScrolling();
                    internalData.lastScrollLeft = scrollLeft;
                }
                if (isRollY) {
                    const yThreshold = computeScrollYThreshold.value;
                    isTop = scrollTop <= 1;
                    if (!isTop) {
                        isBottom = scrollTop + bodyHeight >= scrollHeight - 1;
                    }
                    if (scrollTop > lastScrollTop) {
                        direction = 'bottom';
                        if (scrollTop + bodyHeight >= scrollHeight - yThreshold) {
                            isBottomBoundary = true;
                        }
                    }
                    else {
                        direction = 'top';
                        if (scrollTop <= yThreshold) {
                            isTopBoundary = true;
                        }
                    }
                    internalData.lastScrollTop = scrollTop;
                }
                internalData.lastSTime = Date.now();
                const evntParams = Object.assign({ source: sourceType, scrollTop,
                    scrollLeft,
                    bodyHeight,
                    bodyWidth,
                    scrollHeight,
                    scrollWidth, isX: isRollX, isY: isRollY, isTop,
                    isBottom,
                    isLeft,
                    isRight,
                    direction }, params);
                updateRowExpandStyle();
                checkLastSyncScroll(isRollX, isRollY);
                if (isRollX) {
                    $xeTable.closeFilter();
                }
                if (rowOpts.isHover || highlightHoverRow) {
                    $xeTable.clearHoverRow();
                }
                if (validTip && validTip.reactData.visible) {
                    validTip.close();
                }
                if (tooltip && tooltip.reactData.visible) {
                    tooltip.close();
                }
                if (isBottomBoundary || isTopBoundary || isRightBoundary || isLeftBoundary) {
                    dispatchEvent('scroll-boundary', evntParams, evnt);
                }
                dispatchEvent('scroll', evntParams, evnt);
            },
            /**
             * 横向 X 可视渲染事件处理
             */
            triggerScrollXEvent() {
                const virtualXOpts = computeVirtualXOpts.value;
                if (virtualXOpts.immediate) {
                    loadScrollXData();
                }
                else {
                    lazyScrollXData();
                }
            },
            /**
             * 纵向 Y 可视渲染事件处理
             */
            triggerScrollYEvent() {
                const virtualYOpts = computeVirtualYOpts.value;
                if (virtualYOpts.immediate) {
                    loadScrollYData();
                }
                else {
                    lazyScrollYData();
                }
            },
            triggerBodyScrollEvent(evnt, fixedType) {
                const { scrollYLoad, scrollXLoad } = reactData;
                const { elemStore, intoRunScroll, lastScrollTop, lastScrollLeft, inWheelScroll, inVirtualScroll, inHeaderScroll, inBodyScroll, scrollRenderType, inFooterScroll } = internalData;
                if (inWheelScroll || inVirtualScroll || inHeaderScroll || inFooterScroll) {
                    return;
                }
                const xHandleEl = refScrollXHandleElem.value;
                const yHandleEl = refScrollYHandleElem.value;
                const leftScrollElem = getRefElem(elemStore['left-body-scroll']);
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const rightScrollElem = getRefElem(elemStore['right-body-scroll']);
                const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
                const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
                const rowExpandEl = refRowExpandElem.value;
                if (intoRunScroll) {
                    return;
                }
                if (!bodyScrollElem) {
                    return;
                }
                if (!xHandleEl) {
                    return;
                }
                if (!yHandleEl) {
                    return;
                }
                if (inBodyScroll) {
                    if (scrollRenderType !== fixedType) {
                        return;
                    }
                }
                let scrollTop = yHandleEl.scrollTop;
                let scrollLeft = xHandleEl.scrollLeft;
                if (leftScrollElem && fixedType === 'left') {
                    scrollTop = leftScrollElem.scrollTop;
                }
                else if (rightScrollElem && fixedType === 'right') {
                    scrollTop = rightScrollElem.scrollTop;
                }
                else {
                    scrollTop = bodyScrollElem.scrollTop;
                    scrollLeft = bodyScrollElem.scrollLeft;
                }
                const isRollX = scrollLeft !== lastScrollLeft;
                const isRollY = scrollTop !== lastScrollTop;
                internalData.inBodyScroll = true;
                internalData.scrollRenderType = fixedType;
                if (isRollY) {
                    if (fixedType === 'left') {
                        setScrollTop(bodyScrollElem, scrollTop);
                        setScrollTop(rightScrollElem, scrollTop);
                    }
                    else if (fixedType === 'right') {
                        setScrollTop(bodyScrollElem, scrollTop);
                        setScrollTop(leftScrollElem, scrollTop);
                    }
                    else {
                        setScrollTop(leftScrollElem, scrollTop);
                        setScrollTop(rightScrollElem, scrollTop);
                    }
                    setScrollTop(yHandleEl, scrollTop);
                    setScrollTop(rowExpandEl, scrollTop);
                    syncGanttScrollTop(scrollTop);
                    if (scrollYLoad) {
                        $xeTable.triggerScrollYEvent(evnt);
                    }
                }
                if (isRollX) {
                    setScrollLeft(xHandleEl, scrollLeft);
                    setScrollLeft(headerScrollElem, scrollLeft);
                    setScrollLeft(footerScrollElem, scrollLeft);
                    if (scrollXLoad) {
                        $xeTable.triggerScrollXEvent(evnt);
                    }
                }
                $xeTable.handleScrollEvent(evnt, isRollY, isRollX, scrollTop, scrollLeft, {
                    type: 'body',
                    fixed: fixedType
                });
            },
            triggerHeaderScrollEvent(evnt, fixedType) {
                const { scrollXLoad } = reactData;
                const { elemStore, intoRunScroll, inWheelScroll, inVirtualScroll, inBodyScroll, inFooterScroll } = internalData;
                if (inWheelScroll || inVirtualScroll || inBodyScroll || inFooterScroll) {
                    return;
                }
                const yHandleEl = refScrollYHandleElem.value;
                const xHandleEl = refScrollXHandleElem.value;
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
                const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
                if (intoRunScroll) {
                    return;
                }
                if (!headerScrollElem) {
                    return;
                }
                if (!xHandleEl) {
                    return;
                }
                if (!yHandleEl) {
                    return;
                }
                const scrollTop = yHandleEl.scrollTop;
                const scrollLeft = headerScrollElem.scrollLeft;
                const isRollX = true;
                const isRollY = false;
                internalData.inHeaderScroll = true;
                setScrollLeft(xHandleEl, scrollLeft);
                setScrollLeft(footerScrollElem, scrollLeft);
                setScrollLeft(bodyScrollElem, scrollLeft);
                if (scrollXLoad) {
                    $xeTable.triggerScrollXEvent(evnt);
                }
                $xeTable.handleScrollEvent(evnt, isRollY, isRollX, scrollTop, scrollLeft, {
                    type: 'header',
                    fixed: fixedType
                });
            },
            triggerFooterScrollEvent(evnt, fixedType) {
                const { scrollXLoad } = reactData;
                const { elemStore, intoRunScroll, inWheelScroll, inVirtualScroll, inHeaderScroll, inBodyScroll } = internalData;
                if (inWheelScroll || inVirtualScroll || inHeaderScroll || inBodyScroll) {
                    return;
                }
                const yHandleEl = refScrollYHandleElem.value;
                const xHandleEl = refScrollXHandleElem.value;
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
                const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
                if (intoRunScroll) {
                    return;
                }
                if (!footerScrollElem) {
                    return;
                }
                if (!xHandleEl) {
                    return;
                }
                if (!yHandleEl) {
                    return;
                }
                const scrollTop = yHandleEl.scrollTop;
                const scrollLeft = footerScrollElem.scrollLeft;
                const isRollX = true;
                const isRollY = false;
                internalData.inFooterScroll = true;
                setScrollLeft(xHandleEl, scrollLeft);
                setScrollLeft(headerScrollElem, scrollLeft);
                setScrollLeft(bodyScrollElem, scrollLeft);
                if (scrollXLoad) {
                    $xeTable.triggerScrollXEvent(evnt);
                }
                $xeTable.handleScrollEvent(evnt, isRollY, isRollX, scrollTop, scrollLeft, {
                    type: 'footer',
                    fixed: fixedType
                });
            },
            triggerBodyWheelEvent(evnt) {
                const { target, deltaY, deltaX, shiftKey } = evnt;
                if (target && /^textarea$/i.test(target.tagName)) {
                    return;
                }
                // 如果滚轮未移动或者触摸板未变化位置
                if (!deltaY && !deltaX) {
                    return;
                }
                const { highlightHoverRow } = tableProps;
                const { scrollXLoad, scrollYLoad, overflowX, overflowY, expandColumn } = reactData;
                const leftFixedWidth = computeLeftFixedWidth.value;
                const rightFixedWidth = computeRightFixedWidth.value;
                const { elemStore, lastScrollTop, lastScrollLeft } = internalData;
                const rowOpts = computeRowOpts.value;
                const scrollbarXOpts = computeScrollbarXOpts.value;
                const scrollbarYOpts = computeScrollbarYOpts.value;
                const xHandleEl = refScrollXHandleElem.value;
                const yHandleEl = refScrollYHandleElem.value;
                const leftScrollElem = getRefElem(elemStore['left-body-scroll']);
                const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
                const rightScrollElem = getRefElem(elemStore['right-body-scroll']);
                const rowExpandEl = refRowExpandElem.value;
                if (!bodyScrollElem) {
                    return;
                }
                const wheelSpeed = getWheelSpeed(internalData.lastSTime);
                const deltaTop = shiftKey ? 0 : (deltaY * wheelSpeed);
                const deltaLeft = (shiftKey ? (deltaX || deltaY) : deltaX) * wheelSpeed;
                const currScrollTop = bodyScrollElem.scrollTop;
                const currScrollLeft = bodyScrollElem.scrollLeft;
                const scrollTop = Math.max(0, currScrollTop + deltaTop);
                const scrollLeft = Math.max(0, currScrollLeft + deltaLeft);
                const isRollX = overflowX && scrollLeft !== lastScrollLeft;
                const isRollY = overflowY && scrollTop !== lastScrollTop;
                if (isRollX) {
                    // 如果禁用滚动
                    if (scrollbarXOpts.visible === 'hidden') {
                        evnt.preventDefault();
                        return;
                    }
                }
                if (isRollY) {
                    // 如果禁用滚动
                    if (scrollbarYOpts.visible === 'hidden') {
                        evnt.preventDefault();
                        return;
                    }
                    const isTopWheel = deltaTop < 0;
                    // 如果滚动位置已经是顶部或底部,则不需要触发
                    if (isTopWheel ? currScrollTop <= 0 : currScrollTop >= bodyScrollElem.scrollHeight - bodyScrollElem.clientHeight) {
                        return;
                    }
                }
                // 展开行处理,如果展开行嵌入表格中
                if ($xeParentTable) {
                    if (isRollY) {
                        if (checkTargetElement(evnt.target, [leftScrollElem, bodyScrollElem, rightScrollElem], evnt.currentTarget)) {
                            evnt.stopPropagation();
                            return;
                        }
                    }
                    if (isRollX) {
                        if (checkTargetElement(evnt.target, [headerScrollElem, bodyScrollElem, footerScrollElem], evnt.currentTarget)) {
                            evnt.stopPropagation();
                            return;
                        }
                    }
                }
                if (!(isRollX || leftFixedWidth || rightFixedWidth || expandColumn)) {
                    return;
                }
                if (rowOpts.isHover || highlightHoverRow) {
                    $xeTable.clearHoverRow();
                }
                // 用于鼠标纵向滚轮处理
                if (isRollX) {
                    evnt.preventDefault();
                    internalData.inWheelScroll = true;
                    wheelScrollLeftTo(scrollLeft, (offsetLeft) => {
                        internalData.inWheelScroll = true;
                        const currLeftNum = offsetLeft;
                        setScrollLeft(xHandleEl, currLeftNum);
                        setScrollLeft(bodyScrollElem, currLeftNum);
                        setScrollLeft(headerScrollElem, currLeftNum);
                        setScrollLeft(footerScrollElem, currLeftNum);
                        if (scrollXLoad) {
                            $xeTable.triggerScrollXEvent(evnt);
                        }
                        $xeTable.handleScrollEvent(evnt, isRollY, isRollX, bodyScrollElem.scrollTop, currLeftNum, {
                            type: 'table',
                            fixed: ''
                        });
                    });
                }
                if (isRollY) {
                    evnt.preventDefault();
                    internalData.inWheelScroll = true;
                    wheelScrollTopTo(scrollTop, (offsetTop) => {
                        internalData.inWheelScroll = true;
                        const currTopNum = offsetTop;
                        setScrollTop(yHandleEl, currTopNum);
                        setScrollTop(bodyScrollElem, currTopNum);
                        setScrollTop(leftScrollElem, currTopNum);
                        setScrollTop(rightScrollElem, currTopNum);
                        setScrollTop(rowExpandEl, currTopNum);
                        syncGanttScrollTop(currTopNum);
                        if (scrollYLoad) {
                            $xeTable.triggerScrollYEvent(evnt);
                        }
                        $xeTable.handleScrollEvent(evnt, isRollY, isRollX, offsetTop, bodyScrollElem.scrollLeft, {
                            type: 'table',
                            fixed: ''
                        });
                    });
                }
            },
            triggerVirtualScrollXEvent(evnt) {
                const { scrollXLoad } = reactData;
                const { elemStore, inWheelScroll, lastScrollTop, inHeaderScroll, inBodyScroll, inFooterScroll } = internalData;
                if (inHeaderScroll || inBodyScroll || inFooterScroll) {
                    return;
                }
                if (inWheelScroll) {
                    return;
                }
                const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
                const yHandleEl = refScrollYHandleElem.value;
                const wrapperEl = evnt.currentTarget;
                const { scrollLeft } = wrapperEl;
                const yBodyEl = yHandleEl || bodyScrollElem;
                let scrollTop = 0;
                if (yBodyEl) {
                    scrollTop = yBodyEl.scrollTop;
                }
                const isRollX = true;
                const isRollY = scrollTop !== lastScrollTop;
                internalData.inVirtualScroll = true;
                setScrollLeft(bodyScrollElem, scrollLeft);
                setScrollLeft(headerScrollElem, scrollLeft);
                setScrollLeft(footerScrollElem, scrollLeft);
                if (scrollXLoad) {
                    $xeTable.triggerScrollXEvent(evnt);
                }
                $xeTable.handleScrollEvent(evnt, isRollY, isRollX, scrollTop, scrollLeft, {
                    type: 'table',
                    fixed: ''
                });
            },
            triggerVirtualScrollYEvent(evnt) {
                const { scrollYLoad } = reactData;
                const { elemStore, inWheelScroll, lastScrollLeft, inHeaderScroll, inBodyScroll, inFooterScroll } = internalData;
                if (inHeaderScroll || inBodyScroll || inFooterScroll) {
                    return;
                }
                if (inWheelScroll) {
                    return;
                }
                const leftScrollElem = getRefElem(elemStore['left-body-scroll']);
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const rightScrollElem = getRefElem(elemStore['right-body-scroll']);
                const rowExpandEl = refRowExpandElem.value;
                const xHandleEl = refScrollXHandleElem.value;
                const wrapperEl = evnt.currentTarget;
                const { scrollTop } = wrapperEl;
                const xBodyEl = xHandleEl || bodyScrollElem;
                let scrollLeft = 0;
                if (xBodyEl) {
                    scrollLeft = xBodyEl.scrollLeft;
                }
                const isRollX = scrollLeft !== lastScrollLeft;
                const isRollY = true;
                internalData.inVirtualScroll = true;
                setScrollTop(bodyScrollElem, scrollTop);
                setScrollTop(leftScrollElem, scrollTop);
                setScrollTop(rightScrollElem, scrollTop);
                setScrollTop(rowExpandEl, scrollTop);
                syncGanttScrollTop(scrollTop);
                if (scrollYLoad) {
                    $xeTable.triggerScrollYEvent(evnt);
                }
                $xeTable.handleScrollEvent(evnt, isRollY, isRollX, scrollTop, scrollLeft, {
                    type: 'table',
                    fixed: ''
                });
            },
            /**
             * 对于树形结构中,可以直接滚动到指定深层节点中
             * 对于某些特定的场景可能会用到,比如定位到某一节点
             * @param {Row} row 行对象
             */
            scrollToTreeRow(row) {
                const { treeConfig } = props;
                const { isRowGroupStatus } = reactData;
                const { tableFullData } = internalData;
                const rests = [];
                if (treeConfig || isRowGroupStatus) {
                    const aggregateOpts = computeAggregateOpts.value;
                    const treeOpts = computeTreeOpts.value;
                    const childrenField = treeOpts.children || treeOpts.childrenField;
                    const matchObj = XEUtils.findTree(tableFullData, item => $xeTable.eqRow(item, row), { children: isRowGroupStatus ? aggregateOpts.mapChildrenField : childrenField });
                    if (matchObj) {
                        const nodes = matchObj.nodes;
                        nodes.forEach((row, index) => {
                            if (index < nodes.length - 1 && !$xeTable.isTreeExpandByRow(row)) {
                                rests.push($xeTable.setTreeExpand(row, true));
                            }
                        });
                    }
                }
                return Promise.all(rests).then(() => rowToVisible($xeTable, row));
            },
            updateScrollYStatus,
            // 更新横向 X 可视渲染上下剩余空间大小
            updateScrollXSpace() {
                const { scrollXLoad, overflowX, scrollXWidth } = reactData;
                const { visibleColumn, scrollXStore, elemStore, fullColumnIdData } = internalData;
                const $xeGanttView = internalData.xeGanttView;
                const mouseOpts = computeMouseOpts.value;
                const tableBody = refTableBody.value;
                const tableBodyElem = tableBody ? tableBody.$el : null;
                if (tableBodyElem) {
                    const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                    const bodyTableElem = getRefElem(elemStore['main-body-table']);
                    const headerTableElem = getRefElem(elemStore['main-header-table']);
                    const footerTableElem = getRefElem(elemStore['main-footer-table']);
                    let xSpaceLeft = 0;
                    const firstColumn = visibleColumn[scrollXStore.startIndex];
                    if (firstColumn) {
                        const colRest = fullColumnIdData[firstColumn.id] || {};
                        xSpaceLeft = colRest.oLeft;
                    }
                    let clientWidth = 0;
                    if (bodyScrollElem) {
                        clientWidth = bodyScrollElem.clientWidth;
                    }
                    // 虚拟渲染
                    let isScrollXBig = false;
                    let ySpaceWidth = scrollXWidth;
                    if (scrollXWidth > maxXWidth) {
                        // 触右
                        if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollLeft + clientWidth >= maxXWidth) {
                            xSpaceLeft = maxXWidth - bodyTableElem.clientWidth;
                        }
                        else {
                            xSpaceLeft = (maxXWidth - clientWidth) * (xSpaceLeft / (scrollXWidth - clientWidth));
                        }
                        ySpaceWidth = maxXWidth;
                        isScrollXBig = true;
                    }
                    if (!(scrollXLoad && overflowX)) {
                        xSpaceLeft = 0;
                    }
                    if (getConfig().scrollMarginStyle) {
                        // 已废弃方式
                        if (headerTableElem) {
                            headerTableElem.style.marginLeft = headerTableElem.getAttribute('xvm') ? `${xSpaceLeft}px` : '';
                        }
                        if (bodyTableElem) {
                            bodyTableElem.style.marginLeft = `${xSpaceLeft}px`;
                        }
                        if (footerTableElem) {
                            footerTableElem.style.marginLeft = footerTableElem.getAttribute('xvm') ? `${xSpaceLeft}px` : '';
                        }
                    }
                    else {
                        if (headerTableElem) {
                            headerTableElem.style.transform = headerTableElem.getAttribute('xvm') ? `translate(${xSpaceLeft}px, 0px)` : '';
                        }
                        if (bodyTableElem) {
                            bodyTableElem.style.transform = `translate(${xSpaceLeft}px, ${reactData.scrollYTop || 0}px)`;
                        }
                        if (footerTableElem) {
                            footerTableElem.style.transform = footerTableElem.getAttribute('xvm') ? `translate(${xSpaceLeft}px, 0px)` : '';
                        }
                    }
                    const containerList = ['main'];
                    containerList.forEach(name => {
                        const layoutList = ['header', 'body', 'footer'];
                        layoutList.forEach(layout => {
                            const xSpaceElem = getRefElem(elemStore[`${name}-${layout}-xSpace`]);
                            if (xSpaceElem) {
                                xSpaceElem.style.width = scrollXLoad ? `${ySpaceWidth}px` : '';
                            }
                        });
                    });
                    reactData.scrollXLeft = xSpaceLeft;
                    reactData.scrollXWidth = ySpaceWidth;
                    reactData.isScrollXBig = isScrollXBig;
                    const scrollXSpaceEl = refScrollXSpaceElem.value;
                    if (scrollXSpaceEl) {
                        scrollXSpaceEl.style.width = `${ySpaceWidth}px`;
                    }
                    calcScrollbar();
                    if (isScrollXBig && mouseOpts.area) {
                        errLog('vxe.error.notProp', ['mouse-config.area']);
                    }
                    if ($xeGanttView && $xeGanttView.handleUpdateSXSpace) {
                        $xeGanttView.handleUpdateSXSpace();
                    }
                    return nextTick().then(() => {
                        updateStyle();
                    });
                }
            },
            // 更新纵向 Y 可视渲染上下剩余空间大小
            updateScrollYSpace() {
                const { isAllOverflow, overflowY, scrollYLoad, scrollYHeight, expandColumn } = reactData;
                const { scrollYStore, elemStore, isResizeCellHeight, afterFullData, fullAllDataRowIdData, rowExpandedMaps } = internalData;
                const $xeGanttView = internalData.xeGanttView;
                const { startIndex } = scrollYStore;
                const mouseOpts = computeMouseOpts.value;
                const expandOpts = computeExpandOpts.value;
                const rowOpts = computeRowOpts.value;
                const cellOpts = computeCellOpts.value;
                const defaultRowHeight = computeDefaultRowHeight.value;
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const bodyTableElem = getRefElem(elemStore['main-body-table']);
                const leftBodyTableElem = getRefElem(elemStore['left-body-table']);
                const rightbodyTableElem = getRefElem(elemStore['right-body-table']);
                const containerList = ['main', 'left', 'right'];
                let ySpaceTop = 0;
                let sYHeight = scrollYHeight;
                let isScrollYBig = false;
                if (scrollYLoad) {
                    const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height;
                    if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
                        sYHeight = afterFullData.length * defaultRowHeight;
                        if (sYHeight > maxYHeight) {
                            isScrollYBig = true;
                        }
                        ySpaceTop = Math.max(0, startIndex * defaultRowHeight);
                    }
                    else {
                        const firstRow = afterFullData[startIndex];
                        if (firstRow) {
                            let rowid = getRowid($xeTable, firstRow);
                            let rowRest = fullAllDataRowIdData[rowid] || {};
                            ySpaceTop = (rowRest.oTop || 0);
                            const lastRow = afterFullData[afterFullData.length - 1];
                            rowid = getRowid($xeTable, lastRow);
                            rowRest = fullAllDataRowIdData[rowid] || {};
                            if (rowRest) {
                                const rHeight = getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight);
                                // 如果为空时还没计算完数据,保持原高度不变
                                if (rHeight) {
                                    sYHeight = (rowRest.oTop || 0) + rHeight;
                                    // 是否展开行
                                    if (expandColumn && rowExpandedMaps[rowid]) {
                                        sYHeight += rowRest.expandHeight || expandOpts.height || 0;
                                    }
                                }
                            }
                            if (sYHeight > maxYHeight) {
                                isScrollYBig = true;
                            }
                        }
                        else {
                            sYHeight = bodyTableElem ? bodyTableElem.clientHeight : 0;
                        }
                    }
                }
                else {
                    if (bodyTableElem) {
                        sYHeight = bodyTableElem.clientHeight;
                    }
                }
                let clientHeight = 0;
                if (bodyScrollElem) {
                    clientHeight = bodyScrollElem.clientHeight;
                }
                // 虚拟渲染
                let ySpaceHeight = sYHeight;
                let scrollYTop = ySpaceTop;
                if (isScrollYBig) {
                    // 触底
                    if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollTop + clientHeight >= maxYHeight) {
                        scrollYTop = maxYHeight - bodyTableElem.clientHeight;
                    }
                    else {
                        scrollYTop = (maxYHeight - clientHeight) * (ySpaceTop / (scrollYHeight - clientHeight));
                    }
                    ySpaceHeight = maxYHeight;
                }
                if (!(scrollYLoad && overflowY)) {
                    scrollYTop = 0;
                }
                if (getConfig().scrollMarginStyle) {
                    if (leftBodyTableElem) {
                        leftBodyTableElem.style.marginTop = `${scrollYTop}px`;
                    }
                    if (bodyTableElem) {
                        bodyTableElem.style.marginTop = `${scrollYTop}px`;
                    }
                    if (rightbodyTableElem) {
                        rightbodyTableElem.style.marginTop = `${scrollYTop}px`;
                    }
                }
                else {
                    if (leftBodyTableElem) {
                        leftBodyTableElem.style.transform = `translate(0px, ${scrollYTop}px)`;
                    }
                    if (bodyTableElem) {
                        bodyTableElem.style.transform = `translate(${reactData.scrollXLeft || 0}px, ${scrollYTop}px)`;
                    }
                    if (rightbodyTableElem) {
                        rightbodyTableElem.style.transform = `translate(0px, ${scrollYTop}px)`;
                    }
                }
                containerList.forEach(name => {
                    const layoutList = ['header', 'body', 'footer'];
                    layoutList.forEach(layout => {
                        const ySpaceElem = getRefElem(elemStore[`${name}-${layout}-ySpace`]);
                        if (ySpaceElem) {
                            ySpaceElem.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
                        }
                    });
                });
                const scrollYSpaceEl = refScrollYSpaceElem.value;
                if (scrollYSpaceEl) {
                    scrollYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
                }
                const rowExpandYSpaceEl = refRowExpandYSpaceElem.value;
                if (rowExpandYSpaceEl) {
                    rowExpandYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
                }
                reactData.scrollYTop = scrollYTop;
                reactData.scrollYHeight = isScrollYBig ? sYHeight : ySpaceHeight;
                reactData.isScrollYBig = isScrollYBig;
                calcScrollbar();
                if (isScrollYBig && mouseOpts.area) {
                    errLog('vxe.error.notProp', ['mouse-config.area']);
                }
                if ($xeGanttView && $xeGanttView.handleUpdateSYSpace) {
                    $xeGanttView.handleUpdateSYSpace();
                }
                return nextTick().then(() => {
                    return updateStyle();
                });
            },
            updateScrollXData() {
                const { isAllOverflow } = reactData;
                handleTableColumn();
                $xeTable.updateScrollXSpace();
                return nextTick().then(() => {
                    handleTableColumn();
                    $xeTable.updateScrollXSpace();
                    if (!isAllOverflow) {
                        $xeTable.updateScrollYSpace();
                    }
                });
            },
            updateScrollYData() {
                $xeTable.handleTableData();
                $xeTable.updateScrollYSpace();
                return nextTick().then(() => {
                    $xeTable.handleTableData();
                    $xeTable.updateScrollYSpace();
                });
            },
            /**
             * 处理固定列的显示状态
             */
            checkScrolling() {
                const { elemStore } = internalData;
                const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
                const leftContainerElem = refLeftContainer.value;
                const rightContainerElem = refRightContainer.value;
                const xHandleEl = refScrollXHandleElem.value;
                const bodtTargetEl = xHandleEl || bodyScrollElem;
                if (bodtTargetEl) {
                    if (leftContainerElem) {
                        if (bodtTargetEl.scrollLeft > 0) {
                            addClass(leftContainerElem, 'scrolling--middle');
                        }
                        else {
                            removeClass(leftContainerElem, 'scrolling--middle');
                        }
                    }
                    if (rightContainerElem) {
                        if (bodtTargetEl.clientWidth < bodtTargetEl.scrollWidth - Math.ceil(bodtTargetEl.scrollLeft)) {
                            addClass(rightContainerElem, 'scrolling--middle');
                        }
                        else {
                            removeClass(rightContainerElem, 'scrolling--middle');
                        }
                    }
                }
            },
            handleUpdateAggData() {
                return loadTableData(internalData.tableSynchData, false, true);
            },
            handlePushStack() {
                const keyboardOpts = computeKeyboardOpts.value;
                if (!keyboardOpts.isUndoRedo) {
                    return;
                }
                const { stackHistoryStore } = internalData;
                const stackObj = getSnapshotStackData();
                stackHistoryStore.undoStacks.push(stackObj);
                stackHistoryStore.redoStacks = [];
                truncateStackHistory();
            },
            handleUndoStackEvent(evnt) {
                const { stackHistoryStore } = internalData;
                const { undoStacks, redoStacks } = stackHistoryStore;
                if (undoStacks.length) {
                    const stackObj = getSnapshotStackData();
                    redoStacks.push(stackObj);
                    handleUpdateSnapshotStackData(undoStacks.pop());
                    if (evnt) {
                        dispatchEvent('undo', {}, evnt);
                    }
                    return nextTick(() => {
                        return { status: true };
                    });
                }
                return Promise.resolve({ status: false });
            },
            handleRedoStackEvent(evnt) {
                const { stackHistoryStore } = internalData;
                const { undoStacks, redoStacks } = stackHistoryStore;
                if (redoStacks.length) {
                    const stackObj = getSnapshotStackData();
                    undoStacks.push(stackObj);
                    handleUpdateSnapshotStackData(redoStacks.pop());
                    if (evnt) {
                        dispatchEvent('redo', {}, evnt);
                    }
                    return nextTick(() => {
                        return { status: true };
                    });
                }
                return Promise.resolve({ status: false });
            },
            handleClearStack() {
                const { stackHistoryStore } = internalData;
                stackHistoryStore.undoStacks = [];
                stackHistoryStore.redoStacks = [];
                return nextTick();
            },
            updateZindex() {
                if (props.zIndex) {
                    internalData.tZindex = props.zIndex;
                }
                else if (internalData.tZindex < getLastZIndex()) {
                    internalData.tZindex = nextZIndex();
                }
            },
            handleCheckedCheckboxRow,
            /**
             * 行 hover 事件
             */
            triggerHoverEvent(evnt, { row }) {
                $xeTable.setHoverRow(row);
            },
            setHoverRow(row) {
                const $xeGanttView = internalData.xeGanttView;
                const rowid = getRowid($xeTable, row);
                const el = refElem.value;
                $xeTable.clearHoverRow();
                if (el) {
                    XEUtils.arrayEach(el.querySelectorAll(`.vxe-body--row[rowid="${rowid}"]`), elem => addClass(elem, 'row--hover'));
                }
                internalData.hoverRow = row;
                if ($xeGanttView && $xeGanttView.handleUpdateHoverRow) {
                    $xeGanttView.handleUpdateHoverRow(row);
                }
            },
            clearHoverRow() {
                const $xeGanttView = internalData.xeGanttView;
                const el = refElem.value;
                if (el) {
                    XEUtils.arrayEach(el.querySelectorAll('.vxe-body--row.row--hover'), elem => removeClass(elem, 'row--hover'));
                }
                internalData.hoverRow = null;
                if ($xeGanttView && $xeGanttView.handleUpdateHoverRow) {
                    $xeGanttView.handleUpdateHoverRow();
                }
            },
            /**
             * 已废弃,被 getCellElement 替换
             * @deprecated
             */
            getCell(row, column) {
                return $xeTable.getCellElement(row, column);
            },
            findRowIndexOf(list, row) {
                return row ? XEUtils.findIndexOf(list, item => $xeTable.eqRow(item, row)) : -1;
            },
            eqRow(row1, row2) {
                if (row1 && row2) {
                    if (row1 === row2) {
                        return true;
                    }
                    return getRowid($xeTable, row1) === getRowid($xeTable, row2);
                }
                return false;
            },
            handleConnectGanttView($ganttView) {
                if ($ganttView && $ganttView.connectUpdate) {
                    $ganttView.connectUpdate({ $table: $xeTable });
                    internalData.xeGanttView = $ganttView;
                }
                return nextTick();
            }
        };
        // 检测对应模块是否安装
        // 'openExport,openPrint,exportData,openImport,importData,saveFile,readFile,importByFile,print'.split(',').forEach(name => {
        //   ($xeTable as any)[name] = function () {
        //     errLog('vxe.error.reqModule', ['Export'])
        //   }
        // })
        // 'clearValidate,fullValidate,validate'.split(',').forEach(name => {
        //   ($xeTable as any)[name] = function () {
        //     errLog('vxe.error.reqModule', ['Validator'])
        //   }
        // })
        Object.assign($xeTable, tableMethods, tablePrivateMethods);
        /**
         * 渲染浮固定列
         * 分别渲染左边固定列和右边固定列
         * 如果宽度足够情况下,则不需要渲染固定列
         * @param {String} fixedType 固定列类型
         */
        const renderViewFixed = (fixedType) => {
            const { showHeader, showFooter } = props;
            const { tableData, tableColumn, tableGroupColumn, columnStore, footerTableData } = reactData;
            const scrollbarOpts = computeScrollbarOpts.value;
            const scrollbarXOpts = computeScrollbarXOpts.value;
            const scrollbarYOpts = computeScrollbarYOpts.value;
            const { overscrollBehavior: overscrollXBehavior } = scrollbarXOpts;
            const { overscrollBehavior: overscrollYBehavior } = scrollbarYOpts;
            const isFixedLeft = fixedType === 'left';
            const fixedColumn = isFixedLeft ? columnStore.leftList : columnStore.rightList;
            const osXBehavior = XEUtils.eqNull(overscrollXBehavior) ? scrollbarOpts.overscrollBehavior : overscrollXBehavior;
            const osYBehavior = XEUtils.eqNull(overscrollYBehavior) ? scrollbarOpts.overscrollBehavior : overscrollYBehavior;
            return h('div', {
                ref: isFixedLeft ? refLeftContainer : refRightContainer,
                class: [`vxe-table--fixed-${fixedType}-wrapper`, `sx--${scrollbarXOpts.visible}`, `sy--${scrollbarYOpts.visible}`, {
                        [`x-ob--${osXBehavior}`]: osXBehavior,
                        [`y-ob--${osYBehavior}`]: osYBehavior
                    }]
            }, [
                showHeader
                    ? h(TableHeaderComponent, {
                        ref: isFixedLeft ? refTableLeftHeader : refTableRightHeader,
                        fixedType,
                        tableData,
                        tableColumn,
                        tableGroupColumn,
                        fixedColumn
                    })
                    : renderEmptyElement($xeTable),
                h(TableBodyComponent, {
                    ref: isFixedLeft ? refTableLeftBody : refTableRightBody,
                    fixedType,
                    tableData,
                    tableColumn,
                    fixedColumn
                }),
                showFooter
                    ? h(TableFooterComponent, {
                        ref: isFixedLeft ? refTableLeftFooter : refTableRightFooter,
                        footerTableData,
                        tableColumn,
                        fixedColumn,
                        fixedType
                    })
                    : renderEmptyElement($xeTable)
            ]);
        };
        const renderEmptyBody = () => {
            const emptyOpts = computeEmptyOpts.value;
            const emptySlot = slots.empty;
            const emptyParams = { $table: $xeTable, $grid: $xeGrid, gantt: $xeGantt };
            if (emptySlot) {
                return emptySlot(emptyParams);
            }
            else {
                const compConf = emptyOpts.name ? renderer.get(emptyOpts.name) : null;
                const rtEmptyView = compConf ? (compConf.renderTableEmpty || compConf.renderTableEmptyView || compConf.renderEmpty) : null;
                if (rtEmptyView) {
                    return getSlotVNs(rtEmptyView(emptyOpts, emptyParams));
                }
            }
            return getFuncText(props.emptyText) || getI18n('vxe.table.emptyText');
        };
        const renderDragTipContents = () => {
            const { dragConfig } = props;
            const { dragRow, dragCol, dragTipText } = reactData;
            const columnDragOpts = computeColumnDragOpts.value;
            const rowDragOpts = computeRowDragOpts.value;
            const rowDragSlots = rowDragOpts.slots || {};
            const rTipSlot = rowDragSlots.tip || (dragConfig && dragConfig.slots ? dragConfig.slots.rowTip : null);
            const columnDragSlots = columnDragOpts.slots || {};
            const cTipSlot = columnDragSlots.tip;
            const dRow = dragRow || (rowDragOpts.isCrossTableDrag ? crossTableDragRowInfo.row : null);
            if (dRow && rTipSlot) {
                return callSlot(rTipSlot, { row: dRow });
            }
            if (dragCol && cTipSlot) {
                return callSlot(cTipSlot, { column: dragCol });
            }
            return [h('span', dragTipText)];
        };
        const renderDragTip = () => {
            const { dragRow, dragCol } = reactData;
            const rowOpts = computeRowOpts.value;
            const columnOpts = computeColumnOpts.value;
            const rowDragOpts = computeRowDragOpts.value;
            const columnDragOpts = computeColumnDragOpts.value;
            const dRow = dragRow || (rowDragOpts.isCrossTableDrag ? crossTableDragRowInfo.row : null);
            if (rowOpts.drag || columnOpts.drag) {
                return h('div', {
                    class: 'vxe-table--drag-wrapper'
                }, [
                    h('div', {
                        ref: refDragRowLineElem,
                        class: ['vxe-table--drag-row-line', {
                                'is--guides': rowDragOpts.showGuidesStatus
                            }]
                    }),
                    h('div', {
                        ref: refDragColLineElem,
                        class: ['vxe-table--drag-col-line', {
                                'is--guides': columnDragOpts.showGuidesStatus
                            }]
                    }),
                    (dRow && rowDragOpts.showDragTip) || (dragCol && columnDragOpts.showDragTip)
                        ? h('div', {
                            ref: refDragTipElem,
                            class: 'vxe-table--drag-sort-tip'
                        }, [
                            h('div', {
                                class: 'vxe-table--drag-sort-tip-wrapper'
                            }, [
                                h('div', {
                                    class: 'vxe-table--drag-sort-tip-status'
                                }, [
                                    h('span', {
                                        class: ['vxe-table--drag-sort-tip-normal-status', dRow ? getIcon().TABLE_DRAG_STATUS_ROW : getIcon().TABLE_DRAG_STATUS_COLUMN]
                                    }),
                                    h('span', {
                                        class: ['vxe-table--drag-sort-tip-sub-status', getIcon().TABLE_DRAG_STATUS_SUB_ROW]
                                    }),
                                    h('span', {
                                        class: ['vxe-table--drag-sort-tip-disabled-status', getIcon().TABLE_DRAG_DISABLED]
                                    })
                                ]),
                                h('div', {
                                    class: 'vxe-table--drag-sort-tip-content'
                                }, renderDragTipContents())
                            ])
                        ])
                        : renderEmptyElement($xeTable)
                ]);
            }
            return renderEmptyElement($xeTable);
        };
        const renderRowExpandedVNs = () => {
            const { treeConfig } = props;
            const { expandColumn, isRowGroupStatus } = reactData;
            const tableRowExpandedList = computeTableRowExpandedList.value;
            const expandOpts = computeExpandOpts.value;
            const { mode } = expandOpts;
            if (mode !== 'fixed') {
                return renderEmptyElement($xeTable);
            }
            const expandVNs = [
                h('div', {
                    key: 'repY',
                    ref: refRowExpandYSpaceElem
                })
            ];
            if (expandColumn) {
                const { handleGetRowId } = createHandleGetRowId($xeTable);
                tableRowExpandedList.forEach((row) => {
                    const expandOpts = computeExpandOpts.value;
                    const { height: expandHeight, padding, indent } = expandOpts;
                    const { fullAllDataRowIdData, fullColumnIdData } = internalData;
                    const treeOpts = computeTreeOpts.value;
                    const { transform, seqMode } = treeOpts;
                    const cellStyle = {};
                    const rowid = handleGetRowId(row);
                    const rowRest = fullAllDataRowIdData[rowid];
                    const colid = expandColumn.id;
                    const colRest = fullColumnIdData[colid] || {};
                    let rowLevel = 0;
                    let seq = -1;
                    let _rowIndex = -1;
                    let rowIndex = -1;
                    let $rowIndex = -1;
                    if (rowRest) {
                        rowIndex = rowRest.index;
                        $rowIndex = rowRest.$index;
                        _rowIndex = rowRest._index;
                        rowLevel = rowRest.level;
                        seq = rowRest.seq;
                        if (isRowGroupStatus || (treeConfig && transform && seqMode === 'increasing')) {
                            seq = rowRest._index + 1;
                        }
                        else if ((treeConfig && seqMode === 'fixed')) {
                            seq = rowRest._tIndex + 1;
                        }
                    }
                    if (expandHeight) {
                        cellStyle.height = `${expandHeight}px`;
                    }
                    if (isRowGroupStatus || treeConfig) {
                        cellStyle.paddingLeft = `${(rowLevel * (XEUtils.isNumber(indent) ? indent : treeOpts.indent)) + 30}px`;
                    }
                    let columnIndex = -1;
                    let $columnIndex = -1;
                    let _columnIndex = -1;
                    if (colRest) {
                        columnIndex = colRest.index;
                        $columnIndex = colRest.$index;
                        _columnIndex = colRest._index;
                    }
                    const expandParams = {
                        $table: $xeTable,
                        $grid: $xeGrid,
                        $gantt: $xeGantt,
                        seq,
                        column: expandColumn,
                        columnIndex,
                        $columnIndex,
                        _columnIndex,
                        fixed: '',
                        source: 'table',
                        type: 'body',
                        level: rowLevel,
                        rowid,
                        row,
                        rowIndex,
                        $rowIndex,
                        _rowIndex,
                        isHidden: false,
                        isEdit: false,
                        visibleData: [],
                        data: [],
                        items: []
                    };
                    expandVNs.push(h('div', {
                        key: rowid,
                        class: ['vxe-body--row-expanded-cell', {
                                'is--padding': padding,
                                'is--ellipsis': expandHeight
                            }],
                        rowid,
                        style: cellStyle
                    }, [
                        h('div', {
                            class: 'vxe-body--row-expanded-content'
                        }, expandColumn.renderData(expandParams))
                    ]));
                });
            }
            return h('div', {
                ref: refRowExpandElem,
                class: 'vxe-table--row-expanded-wrapper'
            }, expandVNs);
        };
        const renderScrollX = () => {
            return h('div', {
                key: 'vsx',
                ref: refScrollXVirtualElem,
                class: 'vxe-table--scroll-x-virtual'
            }, [
                h('div', {
                    ref: refScrollXLeftCornerElem,
                    class: 'vxe-table--scroll-x-left-corner'
                }),
                h('div', {
                    ref: refScrollXWrapperElem,
                    class: 'vxe-table--scroll-x-wrapper'
                }, [
                    h('div', {
                        ref: refScrollXHandleElem,
                        class: 'vxe-table--scroll-x-handle',
                        onScroll: $xeTable.triggerVirtualScrollXEvent
                    }, [
                        h('div', {
                            ref: refScrollXSpaceElem,
                            class: 'vxe-table--scroll-x-space'
                        })
                    ]),
                    h('div', {
                        class: 'vxe-table--scroll-x-handle-appearance'
                    })
                ]),
                h('div', {
                    ref: refScrollXRightCornerElem,
                    class: 'vxe-table--scroll-x-right-corner'
                })
            ]);
        };
        const renderScrollY = () => {
            return h('div', {
                ref: refScrollYVirtualElem,
                class: 'vxe-table--scroll-y-virtual'
            }, [
                h('div', {
                    ref: refScrollYTopCornerElem,
                    class: 'vxe-table--scroll-y-top-corner'
                }),
                h('div', {
                    ref: refScrollYWrapperElem,
                    class: 'vxe-table--scroll-y-wrapper'
                }, [
                    h('div', {
                        ref: refScrollYHandleElem,
                        class: 'vxe-table--scroll-y-handle',
                        onScroll: $xeTable.triggerVirtualScrollYEvent
                    }, [
                        h('div', {
                            ref: refScrollYSpaceElem,
                            class: 'vxe-table--scroll-y-space'
                        })
                    ]),
                    h('div', {
                        class: 'vxe-table--scroll-y-handle-appearance'
                    })
                ]),
                h('div', {
                    ref: refScrollYBottomCornerElem,
                    class: 'vxe-table--scroll-y-bottom-corner'
                })
            ]);
        };
        const renderViewport = () => {
            const { showHeader, showFooter } = props;
            const { overflowX, tableData, tableColumn, tableGroupColumn, footerTableData, columnStore } = reactData;
            const scrollbarOpts = computeScrollbarOpts.value;
            const scrollbarXOpts = computeScrollbarXOpts.value;
            const scrollbarYOpts = computeScrollbarYOpts.value;
            const { overscrollBehavior: overscrollXBehavior } = scrollbarXOpts;
            const { overscrollBehavior: overscrollYBehavior } = scrollbarYOpts;
            const { leftList, rightList } = columnStore;
            const osXBehavior = XEUtils.eqNull(overscrollXBehavior) ? scrollbarOpts.overscrollBehavior : overscrollXBehavior;
            const osYBehavior = XEUtils.eqNull(overscrollYBehavior) ? scrollbarOpts.overscrollBehavior : overscrollYBehavior;
            return h('div', {
                ref: refTableViewportElem,
                class: ['vxe-table--viewport-wrapper', {
                        [`x-ob--${osXBehavior}`]: osXBehavior,
                        [`y-ob--${osYBehavior}`]: osYBehavior
                    }]
            }, [
                h('div', {
                    class: ['vxe-table--main-wrapper', `sx--${scrollbarXOpts.visible}`, `sy--${scrollbarYOpts.visible}`]
                }, [
                    /**
                     * 表头
                     */
                    showHeader
                        ? h(TableHeaderComponent, {
                            ref: refTableHeader,
                            tableData,
                            tableColumn,
                            tableGroupColumn
                        })
                        : renderEmptyElement($xeTable),
                    /**
                     * 表体
                     */
                    h(TableBodyComponent, {
                        ref: refTableBody,
                        tableData,
                        tableColumn
                    }),
                    /**
                     * 表尾
                     */
                    showFooter
                        ? h(TableFooterComponent, {
                            ref: refTableFooter,
                            footerTableData,
                            tableColumn
                        })
                        : renderEmptyElement($xeTable)
                ]),
                h('div', {
                    class: 'vxe-table--fixed-wrapper'
                }, [
                    leftList && leftList.length && overflowX ? renderViewFixed('left') : renderEmptyElement($xeTable),
                    rightList && rightList.length && overflowX ? renderViewFixed('right') : renderEmptyElement($xeTable)
                ]),
                renderRowExpandedVNs()
            ]);
        };
        const renderBody = () => {
            const scrollbarYToLeft = computeScrollbarYToLeft.value;
            return h('div', {
                class: 'vxe-table--layout-wrapper'
            }, scrollbarYToLeft
                ? [
                    renderScrollY(),
                    renderViewport()
                ]
                : [
                    renderViewport(),
                    renderScrollY()
                ]);
        };
        const renderVN = () => {
            const { loading, stripe, showHeader, height, treeConfig, mouseConfig, showFooter, highlightCell, highlightHoverRow, highlightHoverColumn, editConfig, editRules } = props;
            const { isGroup, overflowX, overflowY, scrollXLoad, scrollYLoad, tableData, initStore, isRowGroupStatus, columnStore, filterStore, customStore, tooltipStore } = reactData;
            const { teleportToWrapperElem, popupToWrapperElem, customPopupToElem } = internalData;
            const { leftList, rightList } = columnStore;
            const loadingSlot = slots.loading;
            const tipSlots = {
                header: slots.headerTooltip || slots['header-tooltip'],
                body: slots.tooltip,
                footer: slots.footerTooltip || slots['footer-tooltip']
            };
            const currTooltipSlot = tooltipStore.visible && tooltipStore.type ? tipSlots[tooltipStore.type] : null;
            const tableStyle = computeTableStyle.value;
            const rowDragOpts = computeRowDragOpts.value;
            const tableTipConfig = computeTableTipConfig.value;
            const validTipConfig = computeValidTipConfig.value;
            const validOpts = computeValidOpts.value;
            const checkboxOpts = computeCheckboxOpts.value;
            const treeOpts = computeTreeOpts.value;
            const rowOpts = computeRowOpts.value;
            const columnOpts = computeColumnOpts.value;
            const vSize = computeSize.value;
            const tableBorder = computeTableBorder.value;
            const mouseOpts = computeMouseOpts.value;
            const areaOpts = computeAreaOpts.value;
            const loadingOpts = computeLoadingOpts.value;
            const isContentMenu = computeIsContentMenu.value;
            const currLoading = reactData.isColLoading || reactData.isRowLoading || loading;
            const resizableOpts = computeResizableOpts.value;
            const isArea = mouseConfig && mouseOpts.area;
            const columnDragOpts = computeColumnDragOpts.value;
            const scrollbarXToTop = computeScrollbarXToTop.value;
            const scrollbarYToLeft = computeScrollbarYToLeft.value;
            const { isCrossTableDrag } = rowDragOpts;
            const tbOns = {
                onKeydown: keydownEvent,
                onContextmenu: contextMenuEvent
            };
            if (isCrossTableDrag && !tableData.length) {
                tbOns.onDragover = $xeTable.handleCrossTableRowDragoverEmptyEvent;
            }
            return h('div', Object.assign({ ref: refElem, class: ['vxe-table', 'vxe-table--render-default', `tid_${xID}`, `border--${tableBorder}`, `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}`, `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}`, {
                        [`size--${vSize}`]: vSize,
                        [`valid-msg--${validOpts.msgMode}`]: !!editRules,
                        'vxe-editable': !!editConfig,
                        'old-cell-valid': editRules && getConfig().cellVaildMode === 'obsolete',
                        'cell--highlight': highlightCell,
                        'cell--selected': mouseConfig && mouseOpts.selected,
                        'cell--area': isArea,
                        'header-cell--area': isArea && areaOpts.selectCellByHeader,
                        'body-cell--area': isArea && areaOpts.selectCellByBody,
                        'row--highlight': rowOpts.isHover || highlightHoverRow,
                        'column--highlight': columnOpts.isHover || highlightHoverColumn,
                        'checkbox--range': checkboxOpts.range,
                        'col--drag-cell': columnOpts.drag && columnDragOpts.trigger === 'cell',
                        'is--header': showHeader,
                        'not--header': !showHeader,
                        'is--footer': showFooter,
                        'not--footer': !showFooter,
                        'is--group': isGroup,
                        'is-row-group': isRowGroupStatus,
                        'is--tree-line': treeConfig && (treeOpts.showLine || treeOpts.line),
                        'is--fixed-left': leftList.length,
                        'is--fixed-right': rightList.length,
                        'is--animat': !!props.animat,
                        'is--round': props.round,
                        'is--stripe': !treeConfig && stripe,
                        'is--loading': currLoading,
                        'is--empty': !currLoading && !tableData.length,
                        'is--scroll-y': overflowY,
                        'not--scroll-y': !overflowY,
                        'is--scroll-x': overflowX,
                        'not--scroll-x': !overflowX,
                        'is--virtual-x': scrollXLoad,
                        'is--virtual-y': scrollYLoad
                    }], style: tableStyle, spellcheck: false }, tbOns), [
                /**
                 * 隐藏列
                 */
                h('div', {
                    class: 'vxe-table-slots'
                }, slots.default ? slots.default({}) : []),
                h('div', {
                    ref: refVarElem,
                    class: 'vxe-table-vars'
                }, [
                    h('div', {
                        class: 'vxe-table-var-default'
                    }),
                    h('div', {
                        class: 'vxe-table-var-medium'
                    }),
                    h('div', {
                        class: 'vxe-table-var-small'
                    }),
                    h('div', {
                        class: 'vxe-table-var-mini'
                    })
                ]),
                h('div', {
                    key: 'tw',
                    class: 'vxe-table--render-wrapper'
                }, scrollbarXToTop
                    ? [
                        renderScrollX(),
                        renderBody()
                    ]
                    : [
                        renderBody(),
                        renderScrollX()
                    ]),
                /**
                 * 空数据
                 */
                h('div', {
                    key: 'tn',
                    ref: refEmptyPlaceholder,
                    class: 'vxe-table--empty-place-wrapper',
                    xid: xID
                }, [
                    h('div', {
                        class: 'vxe-table--empty-placeholder'
                    }, [
                        h('div', {
                            class: 'vxe-table--empty-content'
                        }, renderEmptyBody())
                    ])
                ]),
                /**
                 * 边框线
                 */
                h('div', {
                    key: 'tl',
                    class: 'vxe-table--border-line'
                }),
                /**
                 * 列宽线
                 */
                h('div', {
                    key: 'tcl',
                    ref: refColResizeBar,
                    class: 'vxe-table--resizable-col-bar'
                }, resizableOpts.showDragTip
                    ? [
                        h('div', {
                            class: 'vxe-table--resizable-number-tip'
                        })
                    ]
                    : []),
                h('div', {
                    key: 'ttw'
                }, [
                    h(Teleport, {
                        to: teleportToWrapperElem,
                        disabled: !($xeGantt && teleportToWrapperElem)
                    }, [
                        h('div', {
                            ref: refTeleportWrapper
                        }, [
                            /**
                             * 行高线
                             */
                            h('div', {
                                key: 'trl',
                                ref: refRowResizeBar,
                                class: 'vxe-table--resizable-row-bar'
                            }, resizableOpts.showDragTip
                                ? [
                                    h('div', {
                                        class: 'vxe-table--resizable-number-tip'
                                    })
                                ]
                                : []),
                            /**
                             * 加载中
                             */
                            VxeUILoadingComponent
                                ? h(VxeUILoadingComponent, {
                                    key: 'lg',
                                    class: 'vxe-table--loading',
                                    modelValue: currLoading,
                                    icon: loadingOpts.icon,
                                    text: loadingOpts.text
                                }, loadingSlot
                                    ? {
                                        default: () => callSlot(loadingSlot, { $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, loading: currLoading })
                                    }
                                    : {})
                                : loadingSlot
                                    ? h('div', {
                                        class: ['vxe-loading--custom-wrapper', {
                                                'is--visible': currLoading
                                            }]
                                    }, callSlot(loadingSlot, { $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, loading: currLoading }))
                                    : renderEmptyElement($xeTable),
                            /**
                             * 拖拽排序提示
                             */
                            renderDragTip()
                        ])
                    ])
                ]),
                h('div', {
                    key: 'fpw',
                    ref: refCustomContainerElem
                }, [
                    h(Teleport, {
                        to: customPopupToElem,
                        disabled: !!reactData.ctPopupFlag && !customPopupToElem
                    }, [
                        /**
                         * 自定义列
                         */
                        initStore.custom
                            ? h(TableCustomPanelComponent, {
                                key: 'cs',
                                ref: refTableCustom,
                                customStore
                            })
                            : renderEmptyElement($xeTable)
                    ])
                ]),
                h('div', {
                    key: 'tpw'
                }, [
                    h(Teleport, {
                        to: popupToWrapperElem,
                        disabled: !($xeGGWrapper && popupToWrapperElem)
                    }, [
                        h('div', {
                            ref: refPopupWrapperElem
                        }, [
                            /**
                             * 筛选
                             */
                            initStore.filter
                                ? h(TableFilterPanelComponent, {
                                    key: 'tf',
                                    ref: refTableFilter,
                                    filterStore
                                })
                                : renderEmptyElement($xeTable),
                            /**
                             * 快捷菜单
                             */
                            isContentMenu
                                ? h(TableMenuPanelComponent, {
                                    key: 'tm',
                                    ref: refTableMenu
                                })
                                : renderEmptyElement($xeTable)
                        ])
                    ])
                ]),
                /**
                 * 导入
                 */
                initStore.import && props.importConfig
                    ? h(TableImportPanelComponent, {
                        key: 'it',
                        defaultOptions: reactData.importParams,
                        storeData: reactData.importStore
                    })
                    : renderEmptyElement($xeTable),
                /**
                 * 导出
                 */
                initStore.export && (props.exportConfig || props.printConfig)
                    ? h(TableExportPanelComponent, {
                        key: 'et',
                        defaultOptions: reactData.exportParams,
                        storeData: reactData.exportStore
                    })
                    : renderEmptyElement($xeTable),
                /**
                 * 提示相关
                 */
                VxeUITooltipComponent
                    ? h('div', {}, [
                        /**
                         * 通用提示
                         */
                        h(VxeUITooltipComponent, {
                            key: 'ctp',
                            ref: refCommTooltip,
                            isArrow: false,
                            enterable: false
                        }),
                        /**
                          * 工具提示
                          */
                        h(VxeUITooltipComponent, {
                            key: 'btp',
                            ref: refTooltip,
                            theme: tableTipConfig.theme,
                            enterable: tableTipConfig.enterable,
                            enterDelay: tableTipConfig.enterDelay,
                            leaveDelay: tableTipConfig.leaveDelay,
                            useHtml: XEUtils.isBoolean(tableTipConfig.useHtml) ? tableTipConfig.useHtml : undefined,
                            // 已废弃
                            useHTML: XEUtils.isBoolean(tableTipConfig.useHTML) ? tableTipConfig.useHTML : undefined,
                            width: tableTipConfig.width,
                            height: tableTipConfig.height,
                            minWidth: tableTipConfig.minWidth,
                            minHeight: tableTipConfig.minHeight,
                            maxWidth: tableTipConfig.maxWidth,
                            maxHeight: tableTipConfig.maxHeight,
                            placement: tableTipConfig.placement,
                            defaultPlacement: tableTipConfig.defaultPlacement,
                            popupClassName: tableTipConfig.popupClassName
                        }, currTooltipSlot
                            ? {
                                content: () => {
                                    const { type, row, column, content: tooltipContent } = tooltipStore;
                                    if (currTooltipSlot) {
                                        if (column && type === 'header') {
                                            return h('div', {
                                                key: type
                                            }, currTooltipSlot({ column, tooltipContent, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt }));
                                        }
                                        if (row && column && type === 'body') {
                                            return h('div', {
                                                key: type
                                            }, currTooltipSlot({ row, column, tooltipContent, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt }));
                                        }
                                        if (row && column && type === 'footer') {
                                            return h('div', {
                                                key: type
                                            }, currTooltipSlot({ row, column, tooltipContent, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt }));
                                        }
                                    }
                                    return renderEmptyElement($xeTable);
                                }
                            }
                            : {}),
                        /**
                          * 校验提示
                          */
                        props.editRules && validOpts.showErrorMessage && (validOpts.message === 'default' ? !height : validOpts.message === 'tooltip')
                            ? h(VxeUITooltipComponent, {
                                key: 'vtp',
                                ref: refValidTooltip,
                                class: [{
                                        'old-cell-valid': editRules && getConfig().cellVaildMode === 'obsolete'
                                    }, 'vxe-table--valid-error'],
                                theme: validTipConfig.theme,
                                enterable: validTipConfig.enterable,
                                enterDelay: validTipConfig.enterDelay,
                                leaveDelay: validTipConfig.leaveDelay
                            })
                            : renderEmptyElement($xeTable)
                    ])
                    : renderEmptyElement($xeTable)
            ]);
        };
        const dataFlag = ref(0);
        watch(() => props.data ? props.data.length : -1, () => {
            dataFlag.value++;
        });
        watch(() => props.data, () => {
            dataFlag.value++;
        });
        watch(dataFlag, () => {
            const { initStatus } = internalData;
            const value = props.data || [];
            if (value && value.length >= 20000) {
                warnLog('vxe.error.errLargeData', ['loadData(data), reloadData(data)']);
            }
            loadTableData(value, false, true).then(() => {
                const { scrollXLoad, scrollYLoad, expandColumn } = reactData;
                const expandOpts = computeExpandOpts.value;
                internalData.inited = true;
                internalData.initStatus = true;
                if (!initStatus) {
                    handleLoadDefaults();
                }
                // const checkboxOpts = computeCheckboxOpts.value
                // const checkboxColumn = internalData.tableFullColumn.find(column => column.type === 'checkbox')
                // if (checkboxColumn && internalData.tableFullData.length > 300 && !checkboxOpts.checkField) {
                //   warnLog('vxe.error.checkProp', ['checkbox-config.checkField'])
                // }
                if ((scrollXLoad || scrollYLoad) && (expandColumn && expandOpts.mode !== 'fixed')) {
                    warnLog('vxe.error.scrollErrProp', ['column.type=expand']);
                }
                return $xeTable.recalculate();
            });
        });
        const staticColumnFlag = ref(0);
        watch(() => reactData.staticColumns.length, () => {
            staticColumnFlag.value++;
        });
        watch(() => reactData.staticColumns, () => {
            staticColumnFlag.value++;
        });
        watch(staticColumnFlag, () => {
            nextTick(() => handleInitColumn(XEUtils.clone(reactData.staticColumns)));
        });
        const tableColumnFlag = ref(0);
        watch(() => reactData.tableColumn.length, () => {
            tableColumnFlag.value++;
        });
        watch(() => reactData.tableColumn, () => {
            tableColumnFlag.value++;
        });
        watch(tableColumnFlag, () => {
            $xeTable.analyColumnWidth();
        });
        watch(() => reactData.upDataFlag, () => {
            nextTick(() => {
                $xeTable.updateData();
            });
        });
        watch(() => reactData.reColumnFlag, () => {
            nextTick(() => {
                $xeTable.refreshColumn();
            });
        });
        const reLayoutFlag = ref(0);
        watch(computeSize, () => {
            reLayoutFlag.value++;
        });
        watch(() => props.showHeader, () => {
            reLayoutFlag.value++;
        });
        watch(() => props.showFooter, () => {
            reLayoutFlag.value++;
        });
        watch(() => props.showHeaderOverflow, () => {
            reLayoutFlag.value++;
        });
        watch(() => props.showOverflow, () => {
            updateColumnAllOverflow();
            reLayoutFlag.value++;
        });
        watch(() => props.showFooterOverflow, () => {
            reLayoutFlag.value++;
        });
        watch(() => reactData.overflowX, () => {
            reLayoutFlag.value++;
        });
        watch(() => reactData.overflowY, () => {
            reLayoutFlag.value++;
        });
        watch(() => props.height, () => {
            reLayoutFlag.value++;
        });
        watch(() => props.maxHeight, () => {
            reLayoutFlag.value++;
        });
        watch(computeScrollbarXToTop, () => {
            reLayoutFlag.value++;
        });
        watch(computeScrollbarYToLeft, () => {
            reLayoutFlag.value++;
        });
        watch(() => VxeUI.getLanguage(), () => {
            reLayoutFlag.value++;
        });
        watch(() => {
            const scrollbarXOpts = computeScrollbarXOpts.value;
            return scrollbarXOpts.visible;
        }, () => {
            reLayoutFlag.value++;
        });
        watch(() => {
            const scrollbarYOpts = computeScrollbarYOpts.value;
            return scrollbarYOpts.visible;
        }, () => {
            reLayoutFlag.value++;
        });
        watch(() => {
            const cellOpts = computeCellOpts.value;
            return cellOpts.height;
        }, () => {
            reLayoutFlag.value++;
        });
        watch(reLayoutFlag, () => {
            $xeTable.recalculate(true);
        });
        const footFlag = ref(0);
        watch(() => props.footerData ? props.footerData.length : -1, () => {
            footFlag.value++;
        });
        watch(() => props.footerData, () => {
            footFlag.value++;
        });
        watch(footFlag, () => {
            internalData.footerFullDataRowData = {};
            $xeTable.updateFooter();
        });
        watch(() => props.syncResize, (value) => {
            if (value) {
                handleUpdateResize();
                nextTick(() => {
                    handleUpdateResize();
                    setTimeout(() => handleUpdateResize());
                });
            }
        });
        const mergeCellFlag = ref(0);
        watch(() => props.mergeCells ? props.mergeCells.length : -1, () => {
            mergeCellFlag.value++;
        });
        watch(() => props.mergeCells, () => {
            mergeCellFlag.value++;
        });
        watch(mergeCellFlag, () => {
            handleUpdateMergeBodyCells(props.mergeCells || []);
        });
        const mergeHeaderItemFlag = ref(0);
        watch(() => props.mergeHeaderCells ? props.mergeHeaderCells.length : -1, () => {
            mergeHeaderItemFlag.value++;
        });
        watch(() => props.mergeHeaderCells, () => {
            mergeHeaderItemFlag.value++;
        });
        watch(mergeHeaderItemFlag, () => {
            handleUpdateMergeHeaderCells(props.mergeHeaderCells || []);
        });
        const mergeFooteCellFlag = ref(0);
        watch(() => props.mergeFooterCells ? props.mergeFooterCells.length : -1, () => {
            mergeFooteCellFlag.value++;
        });
        watch(() => props.mergeFooterCells, () => {
            mergeFooteCellFlag.value++;
        });
        watch(() => props.mergeFooterItems ? props.mergeFooterItems.length : -1, () => {
            mergeFooteCellFlag.value++;
        });
        watch(() => props.mergeFooterItems, () => {
            mergeFooteCellFlag.value++;
        });
        watch(mergeFooteCellFlag, () => {
            const mFooterCells = props.mergeFooterCells || props.mergeFooterItems;
            handleUpdateMergeFooterCells(mFooterCells || []);
        });
        watch(computeRowGroupFields, (val) => {
            handleUpdateRowGroup(val);
        });
        watch(computeRowField, () => {
            const { inited, tableFullData } = internalData;
            // 行主键被改变,重载表格
            if (inited) {
                handleKeyField();
                reactData.tableData = [];
                nextTick(() => {
                    $xeTable.reloadData(tableFullData);
                });
            }
        });
        const kfFlag = ref(0);
        watch(() => reactData.updateColFlag, () => {
            kfFlag.value++;
        });
        watch(computeKeepFields, () => {
            kfFlag.value++;
        });
        watch(kfFlag, () => {
            const keepFields = computeKeepFields.value;
            const kpfMaps = {};
            keepFields.forEach(field => {
                kpfMaps[field] = 1;
            });
            internalData.keepUpdateFieldMaps = kpfMaps;
        });
        watch(computeAggregateMode, () => {
            if (reactData.isRowGroupStatus) {
                loadTableData(internalData.tableSynchData, false, true);
            }
        });
        const layoutReFlag = ref(0);
        watch(combineTabsResizeFlag, () => {
            layoutReFlag.value++;
        });
        watch(combineModalResizeFlag, () => {
            layoutReFlag.value++;
        });
        watch(combineSplitterResizeFlag, () => {
            layoutReFlag.value++;
        });
        watch(layoutReFlag, () => {
            handleGlobalResizeEvent();
        });
        handleKeyField();
        hooks.forEach((options) => {
            const { setupTable } = options;
            if (setupTable) {
                const hookRest = setupTable($xeTable);
                if (hookRest && XEUtils.isObject(hookRest)) {
                    Object.assign($xeTable, hookRest);
                }
            }
        });
        $xeTable.preventEvent(null, 'created', { $table: $xeTable });
        let resizeObserver;
        onActivated(() => {
            $xeTable.recalculate().then(() => $xeTable.refreshScroll());
            $xeTable.preventEvent(null, 'activated', { $table: $xeTable });
        });
        onDeactivated(() => {
            const { filterStore } = reactData;
            if (filterStore.visible) {
                $xeTable.clearFilter();
            }
            $xeTable.closeTooltip();
            internalData.isActivated = false;
            $xeTable.preventEvent(null, 'deactivated', { $table: $xeTable });
        });
        onMounted(() => {
            const { editConfig, exportConfig, importConfig, treeConfig, minHeight, keepSource } = props;
            const { scrollXStore, scrollYStore } = internalData;
            const columnOpts = computeColumnOpts.value;
            const columnDragOpts = computeColumnDragOpts.value;
            const aggregateOpts = computeAggregateOpts.value;
            const virtualYOpts = computeVirtualYOpts.value;
            const editOpts = computeEditOpts.value;
            const treeOpts = computeTreeOpts.value;
            const radioOpts = computeRadioOpts.value;
            const checkboxOpts = computeCheckboxOpts.value;
            const expandOpts = computeExpandOpts.value;
            const rowOpts = computeRowOpts.value;
            const customOpts = computeCustomOpts.value;
            const mouseOpts = computeMouseOpts.value;
            const exportOpts = computeExportOpts.value;
            const importOpts = computeImportOpts.value;
            // const currentRowOpts = computeCurrentRowOpts.value
            // const currentColumnOpts = computeCurrentColumnOpts.value
            // const keyboardOpts = computeKeyboardOpts.value
            const rowDragOpts = computeRowDragOpts.value;
            const areaOpts = computeAreaOpts.value;
            const sortOpts = computeSortOpts.value;
            const filterOpts = computeFilterOpts.value;
            const { groupFields } = aggregateOpts;
            if ($xeGantt) {
                const { refClassifyWrapperElem } = $xeGantt.getRefMaps();
                const classifyWrapperEl = refClassifyWrapperElem.value;
                if (classifyWrapperEl) {
                    internalData.teleportToWrapperElem = classifyWrapperEl;
                }
            }
            if ($xeGGWrapper) {
                const { refPopupContainerElem } = $xeGGWrapper.getRefMaps();
                const popupContainerEl = refPopupContainerElem.value;
                if (popupContainerEl) {
                    internalData.popupToWrapperElem = popupContainerEl;
                }
            }
            if (columnOpts.drag || rowOpts.drag || customOpts.allowSort) {
                initTpImg();
            }
            if (props.rowId) {
                warnLog('vxe.error.delProp', ['row-id', 'row-config.keyField']);
            }
            if (props.rowKey) {
                warnLog('vxe.error.delProp', ['row-key', 'row-config.useKey']);
            }
            if (props.columnKey) {
                warnLog('vxe.error.delProp', ['column-id', 'column-config.useKey']);
            }
            if (!(props.rowId || rowOpts.keyField) && (checkboxOpts.reserve || checkboxOpts.checkRowKeys || radioOpts.reserve || radioOpts.checkRowKey || expandOpts.expandRowKeys || treeOpts.expandRowKeys)) {
                warnLog('vxe.error.reqProp', ['row-config.keyField']);
            }
            if (editConfig) {
                if (!keepSource) {
                    if (editOpts.showStatus || editOpts.showUpdateStatus || editOpts.showInsertStatus) {
                        warnLog('vxe.error.reqSupportProp', ['edit-config.showStatus | showUpdateStatus | showInsertStatus', 'keep-source']);
                    }
                    // if (keyboardOpts.isUndoRedo) {
                    //   warnLog('vxe.error.reqSupportProp', ['keyboard-config.isUndoRedo', 'keep-source'])
                    // }
                }
            }
            // if (treeConfig && (treeOpts.showLine || treeOpts.line) && !showOverflow) {
            //   warnLog('vxe.error.reqProp', ['show-overflow'])
            // }
            // if (treeConfig && !treeOpts.transform && props.stripe) {
            //   warnLog('vxe.error.noTree', ['stripe'])
            // }
            if (treeConfig && !treeOpts.transform) {
                if (sortOpts.isDeep) {
                    warnLog('vxe.error.reqSupportProp', ['transform=false', 'sort-config.isDeep=false']);
                }
                if (filterOpts.isDeep) {
                    warnLog('vxe.error.reqSupportProp', ['transform=false', 'filter-config.isDeep=false']);
                }
            }
            if (props.showFooter && !(props.footerMethod || props.footerData)) {
                warnLog('vxe.error.reqProp', ['footer-data | footer-method']);
            }
            if (rowOpts.height) {
                warnLog('vxe.error.delProp', ['row-config.height', 'cell-config.height']);
            }
            if (props.highlightCurrentRow) {
                warnLog('vxe.error.delProp', ['highlight-current-row', 'row-config.isCurrent']);
            }
            if (props.highlightHoverRow) {
                warnLog('vxe.error.delProp', ['highlight-hover-row', 'row-config.isHover']);
            }
            if (props.highlightCurrentColumn) {
                warnLog('vxe.error.delProp', ['highlight-current-column', 'column-config.isCurrent']);
            }
            if (props.highlightHoverColumn) {
                warnLog('vxe.error.delProp', ['highlight-hover-column', 'column-config.isHover']);
            }
            if (props.resizable) {
                warnLog('vxe.error.delProp', ['resizable', 'column-config.resizable']);
            }
            // if (props.virtualXConfig && props.scrollX) {
            //   warnLog('vxe.error.notSupportProp', ['virtual-x-config', 'scroll-x', 'scroll-x=null'])
            // }
            // if (props.virtualYConfig && props.scrollY) {
            //   warnLog('vxe.error.notSupportProp', ['virtual-y-config', 'scroll-y', 'scroll-y=null'])
            // }
            if (props.aggregateConfig && props.rowGroupConfig) {
                warnLog('vxe.error.notSupportProp', ['aggregate-config', 'row-group-config', 'row-group-config=null']);
            }
            // if (props.scrollY) {
            //   warnLog('vxe.error.delProp', ['scroll-y', 'virtual-y-config'])
            // }
            // if (props.scrollX) {
            //   warnLog('vxe.error.delProp', ['scroll-x', 'virtual-x-config'])
            // }
            // 检查导入导出类型,如果自定义导入导出方法,则不校验类型
            if (importConfig && importOpts.types && !importOpts.importMethod && !XEUtils.includeArrays(XEUtils.keys(importOpts._typeMaps), importOpts.types)) {
                warnLog('vxe.error.errProp', [`export-config.types=${importOpts.types.join(',')}`, importOpts.types.filter((type) => XEUtils.includes(XEUtils.keys(importOpts._typeMaps), type)).join(',') || XEUtils.keys(importOpts._typeMaps).join(',')]);
            }
            if (exportConfig && exportOpts.types && !exportOpts.exportMethod && !XEUtils.includeArrays(XEUtils.keys(exportOpts._typeMaps), exportOpts.types)) {
                warnLog('vxe.error.errProp', [`export-config.types=${exportOpts.types.join(',')}`, exportOpts.types.filter((type) => XEUtils.includes(XEUtils.keys(exportOpts._typeMaps), type)).join(',') || XEUtils.keys(exportOpts._typeMaps).join(',')]);
            }
            if (exportConfig && XEUtils.isBoolean(exportOpts.isAllExpand)) {
                warnLog('vxe.error.delProp', ['isAllExpand', 'isTreeAllExpanded']);
            }
            if (!props.id) {
                if ((props.customConfig ? isEnableConf(customOpts) : customOpts.enabled) && customOpts.storage) {
                    errLog('vxe.error.reqProp', ['id']);
                }
            }
            if (props.treeConfig && checkboxOpts.range) {
                errLog('vxe.error.noTree', ['checkbox-config.range']);
            }
            if (rowOpts.height && !props.showOverflow) {
                warnLog('vxe.error.notProp', ['table.show-overflow']);
            }
            if (!$xeTable.triggerClAreaMnEvent) {
                if (props.areaConfig) {
                    warnLog('vxe.error.notProp', ['area-config']);
                }
                if (props.clipConfig) {
                    warnLog('vxe.error.notProp', ['clip-config']);
                }
                if (props.fnrConfig) {
                    warnLog('vxe.error.notProp', ['fnr-config']);
                }
                if (mouseOpts.area) {
                    errLog('vxe.error.notProp', ['mouse-config.area']);
                    return;
                }
                if (mouseOpts.area && areaOpts.selectCellByHeader && columnOpts.drag && columnDragOpts.trigger === 'cell') {
                    errLog('vxe.error.notSupportProp', ['area-config.selectCellByHeader & column-config.drag', 'column-drag-config.trigger=cell', 'column-drag-config.trigger=default | area-config.selectCellByHeader=false']);
                }
            }
            if (!$xeTable.handlePivotTableAggData) {
                if (customOpts.allowGroup) {
                    errLog('vxe.error.notProp', ['custom-config.allowGroup']);
                    return;
                }
                if (customOpts.allowValues) {
                    errLog('vxe.error.notProp', ['custom-config.allowValues']);
                    return;
                }
            }
            if (treeConfig && rowOpts.drag && !treeOpts.transform) {
                errLog('vxe.error.notSupportProp', ['row-config.drag', 'tree-config.transform=false', 'tree-config.transform=true']);
            }
            if (treeConfig && rowDragOpts.isCrossTableDrag && !rowDragOpts.isCrossDrag) {
                errLog('vxe.error.reqSupportProp', ['tree-config & row-drag-config.isCrossTableDrag', 'row-drag-config.isCrossDrag']);
            }
            if (props.dragConfig) {
                warnLog('vxe.error.delProp', ['drag-config', 'row-drag-config']);
            }
            if (props.rowGroupConfig) {
                warnLog('vxe.error.delProp', ['row-group-config', 'aggregate-config']);
            }
            if (aggregateOpts.countFields) {
                warnLog('vxe.error.delProp', ['row-group-config.countFields', 'column.agg-func']);
            }
            if (aggregateOpts.aggregateMethod) {
                warnLog('vxe.error.delProp', ['row-group-config.aggregateMethod', 'aggregate-config.calcValuesMethod']);
            }
            if (aggregateOpts.countMethod) {
                warnLog('vxe.error.delProp', ['aggregate-config.countMethod', 'aggregate-config.calcValuesMethod']);
            }
            if (props.treeConfig && treeOpts.children) {
                warnLog('vxe.error.delProp', ['tree-config.children', 'tree-config.childrenField']);
            }
            if (props.treeConfig && treeOpts.line) {
                warnLog('vxe.error.delProp', ['tree-config.line', 'tree-config.showLine']);
            }
            if (mouseOpts.area && mouseOpts.selected) {
                warnLog('vxe.error.errConflicts', ['mouse-config.area', 'mouse-config.selected']);
            }
            if (mouseOpts.area && (props.treeConfig && !treeOpts.transform)) {
                errLog('vxe.error.notSupportProp', ['mouse-config.area', 'tree-config.transform=false', 'tree-config.transform=true']);
            }
            if (props.editConfig && editOpts.activeMethod) {
                warnLog('vxe.error.delProp', ['edit-config.activeMethod', 'edit-config.beforeEditMethod']);
            }
            if (checkboxOpts.halfField) {
                warnLog('vxe.error.delProp', ['checkbox-config.halfField', 'checkbox-config.indeterminateField']);
            }
            if (props.editConfig && isEnableConf(editOpts) && props.editRules && (minHeight === 0 || minHeight === '0')) {
                warnLog('vxe.error.reqSupportProp', ['edit-config & edit-rules', 'min-height']);
            }
            if (treeConfig) {
                XEUtils.arrayEach(['rowField', 'parentField', 'childrenField', 'hasChildField', 'mapChildrenField'], key => {
                    const val = treeOpts[key];
                    if (val && val.indexOf('.') > -1) {
                        errLog('vxe.error.errProp', [`${key}=${val}`, `${key}=${val.split('.')[0]}`]);
                    }
                });
            }
            if (rowOpts.currentMethod) {
                warnLog('vxe.error.delProp', ['row-config.currentMethod', 'current-row-config.beforeSelectMethod']);
            }
            if (columnOpts.currentMethod) {
                warnLog('vxe.error.delProp', ['row-config.currentMethod', 'current-column-config.beforeSelectMethod']);
            }
            // if ((rowOpts.isCurrent || highlightCurrentRow) && props.keyboardConfig && keyboardOpts.isArrow && !XEUtils.isBoolean(currentRowOpts.isFollowSelected)) {
            //   warnLog('vxe.error.notConflictProp', ['row-config.isCurrent & keyboard-config.isArrow', 'current-row-config.isFollowSelected'])
            // }
            // if ((columnOpts.isCurrent || highlightCurrentColumn) && props.keyboardConfig && keyboardOpts.isArrow && !XEUtils.isBoolean(currentColumnOpts.isFollowSelected)) {
            //   warnLog('vxe.error.notConflictProp', ['column-config.isCurrent & keyboard-config.isArrow', 'current-column-config.isFollowSelected'])
            // }
            // 如果不支持虚拟滚动
            // if (props.spanMethod) {
            //   if (virtualXOpts.enabled) {
            //     warnLog('vxe.error.notConflictProp', ['span-method', 'virtual-x-config.enabled=false'])
            //   }
            //   if (virtualYOpts.enabled) {
            //     warnLog('vxe.error.notConflictProp', ['span-method', 'virtual-y-config.enabled=false'])
            //   }
            // }
            // if (props.footerSpanMethod) {
            //   if (virtualXOpts.enabled) {
            //     warnLog('vxe.error.notConflictProp', ['footer-span-method', 'virtual-x-config.enabled=false'])
            //   }
            // }
            // 检查是否有安装需要的模块
            // if (props.editConfig && !$xeTable.insert) {
            //   errLog('vxe.error.reqModule', ['Edit'])
            // }
            // if (props.editRules && !$xeTable.validate) {
            //   errLog('vxe.error.reqModule', ['Validator'])
            // }
            // if ((checkboxOpts.range || props.keyboardConfig || props.mouseConfig) && !$xeTable.handleCellMousedownEvent) {
            //   errLog('vxe.error.reqModule', ['Keyboard'])
            // }
            // if ((props.printConfig || props.importConfig || props.exportConfig) && !$xeTable.exportData) {
            //   errLog('vxe.error.reqModule', ['Export'])
            // }
            Object.assign(scrollYStore, {
                startIndex: 0,
                endIndex: 0,
                visibleSize: 0
            });
            Object.assign(scrollXStore, {
                startIndex: 0,
                endIndex: 0,
                visibleSize: 0
            });
            handleUpdateRowGroup(groupFields);
            initData();
            nextTick(() => {
                if (props.autoResize) {
                    const el = refElem.value;
                    const parentEl = $xeTable.getParentElem();
                    resizeObserver = globalResize.create(() => {
                        if (props.autoResize) {
                            handleResizeEvent();
                        }
                    });
                    if (el) {
                        resizeObserver.observe(el);
                    }
                    if (parentEl) {
                        resizeObserver.observe(parentEl);
                    }
                }
            });
            if (virtualYOpts.mode !== 'scroll') {
                const tableViewportEl = refTableViewportElem.value;
                if (tableViewportEl) {
                    tableViewportEl.addEventListener('wheel', $xeTable.triggerBodyWheelEvent, { passive: false });
                }
            }
            globalEvents.on($xeTable, 'paste', handleGlobalPasteEvent);
            globalEvents.on($xeTable, 'copy', handleGlobalCopyEvent);
            globalEvents.on($xeTable, 'cut', handleGlobalCutEvent);
            globalEvents.on($xeTable, 'mousedown', handleGlobalMousedownEvent);
            globalEvents.on($xeTable, 'blur', handleGlobalBlurEvent);
            globalEvents.on($xeTable, 'mousewheel', handleGlobalMousewheelEvent);
            globalEvents.on($xeTable, 'keydown', handleGlobalKeydownEvent);
            globalEvents.on($xeTable, 'resize', handleGlobalResizeEvent);
            globalEvents.on($xeTable, 'scroll', handleGlobalScrollEvent);
            globalEvents.on($xeTable, 'contextmenu', $xeTable.handleGlobalContextmenuEvent);
            $xeTable.preventEvent(null, 'mounted', { $table: $xeTable });
        });
        onBeforeUnmount(() => {
            const { _sToTime } = internalData;
            if (_sToTime) {
                clearTimeout(_sToTime);
            }
            const tableViewportEl = refTableViewportElem.value;
            if (tableViewportEl) {
                tableViewportEl.removeEventListener('wheel', $xeTable.triggerBodyWheelEvent);
            }
            internalData.cvCacheMaps = {};
            internalData.prevDragRow = null;
            internalData.prevDragCol = null;
            if (resizeObserver) {
                resizeObserver.disconnect();
            }
            $xeTable.closeTooltip();
            $xeTable.closeFilter();
            if ($xeTable.closeMenu) {
                $xeTable.closeMenu();
            }
            globalEvents.off($xeTable, 'paste');
            globalEvents.off($xeTable, 'copy');
            globalEvents.off($xeTable, 'cut');
            globalEvents.off($xeTable, 'mousedown');
            globalEvents.off($xeTable, 'blur');
            globalEvents.off($xeTable, 'mousewheel');
            globalEvents.off($xeTable, 'keydown');
            globalEvents.off($xeTable, 'resize');
            globalEvents.off($xeTable, 'scroll');
            globalEvents.off($xeTable, 'contextmenu');
            $xeTable.preventEvent(null, 'beforeUnmount', { $table: $xeTable });
            XEUtils.assign(reactData, createReactData());
            XEUtils.assign(internalData, createInternalData());
        });
        onUnmounted(() => {
            $xeTable.preventEvent(null, 'unmounted', { $table: $xeTable });
        });
        nextTick(() => {
            const { showOverflow, showHeaderOverflow, showFooterOverflow } = props;
            const tooltipOpts = computeTooltipOpts.value;
            const headerTooltipOpts = computeHeaderTooltipOpts.value;
            const footerTooltipOpts = computeFooterTooltipOpts.value;
            if (props.loading) {
                if (!VxeUILoadingComponent && !slots.loading) {
                    errLog('vxe.error.reqComp', ['vxe-loading']);
                    errLog('vxe.error.errProp', ['loading=true', 'loading=false | <template #loading>...</template>']);
                }
            }
            if (!VxeUITooltipComponent) {
                let useOvTip = false;
                if (showOverflow === 'tooltip') {
                    useOvTip = true;
                    errLog('vxe.error.errProp', ['show-overflow=' + showOverflow, 'show-overflow=false,title,ellipsis']);
                }
                if (showOverflow === true && tooltipOpts.mode === 'tooltip') {
                    useOvTip = true;
                    errLog('vxe.error.notSupportProp', ['show-overflow=' + showOverflow, 'tooltip-config.mode=tooltip', 'tooltip-config.mode=title,ellipsis']);
                }
                if (showHeaderOverflow === 'tooltip') {
                    useOvTip = true;
                    errLog('vxe.error.errProp', ['show-header-overflow=' + showHeaderOverflow, 'show-header-overflow=false,title,ellipsis']);
                }
                if (showHeaderOverflow === true && headerTooltipOpts.mode === 'tooltip') {
                    useOvTip = true;
                    errLog('vxe.error.notSupportProp', ['show-header-overflow=' + showHeaderOverflow, 'header-tooltip-config.mode=tooltip', 'header-tooltip-config.mode=title,ellipsis']);
                }
                if (showFooterOverflow === 'tooltip') {
                    useOvTip = true;
                    errLog('vxe.error.errProp', ['show-footer-overflow=' + showFooterOverflow, 'show-footer-overflow=false,title,ellipsis']);
                }
                if (showFooterOverflow === true && footerTooltipOpts.mode === 'tooltip') {
                    useOvTip = true;
                    errLog('vxe.error.notSupportProp', ['show-footer-overflow=' + showFooterOverflow, 'footer-tooltip-config.mode=tooltip', 'footer-tooltip-config.mode=title,ellipsis']);
                }
                if (useOvTip) {
                    errLog('vxe.error.reqComp', ['vxe-tooltip']);
                }
            }
        });
        provide('$xeColgroup', null);
        provide('$xeTable', $xeTable);
        $xeTable.renderVN = renderVN;
        return $xeTable;
    },
    render() {
        return this.renderVN();
    }
});