UNPKG

@visactor/vue-vtable

Version:
276 lines (273 loc) 13.3 kB
import { defineComponent, ref, shallowRef, computed, onMounted, onBeforeUnmount, watch, openBlock, createElementBlock, normalizeStyle } from 'vue'; import { PivotChart, PivotTable, ListTable } from '@visactor/vtable'; import { TABLE_EVENTS_KEYS, TABLE_EVENTS } from '../eventsUtils.js'; import { useEditorRender } from '../hooks/useEditorRender.js'; import { useCellRender } from '../hooks/useCellRender.js'; // 创建表格实例 // use Constructor<T> will cause error in rollup-plugin-typescript2, use any temporarily var _sfc_main = /*@__PURE__*/ defineComponent({ __name: 'base-table', props: { type: { type: String, required: false }, options: { type: null, required: false }, records: { type: Array, required: false }, width: { type: [Number, String], required: false, default: '100%' }, height: { type: [Number, String], required: false, default: '100%' }, onReady: { type: Function, required: false }, onError: { type: Function, required: false }, keepColumnWidthChange: { type: Boolean, required: false }, onClickCell: { type: Function, required: false }, onDblClickCell: { type: Function, required: false }, onMouseDownCell: { type: Function, required: false }, onMouseUpCell: { type: Function, required: false }, onSelectedCell: { type: Function, required: false }, onKeyDown: { type: Function, required: false }, onMouseEnterTable: { type: Function, required: false }, onMouseLeaveTable: { type: Function, required: false }, onMouseDownTable: { type: Function, required: false }, onMouseMoveCell: { type: Function, required: false }, onMouseEnterCell: { type: Function, required: false }, onMouseLeaveCell: { type: Function, required: false }, onContextMenuCell: { type: Function, required: false }, onContextMenuCanvas: { type: Function, required: false }, onResizeColumn: { type: Function, required: false }, onResizeColumnEnd: { type: Function, required: false }, onChangeHeaderPosition: { type: Function, required: false }, onChangeHeaderPositionStart: { type: Function, required: false }, onChangeHeaderPositionFail: { type: Function, required: false }, onSortClick: { type: Function, required: false }, onFreezeClick: { type: Function, required: false }, onScroll: { type: Function, required: false }, onDropdownMenuClick: { type: Function, required: false }, onMouseOverChartSymbol: { type: Function, required: false }, onDragSelectEnd: { type: Function, required: false }, onDropdownIconClick: { type: Function, required: false }, onDropdownMenuClear: { type: Function, required: false }, onTreeHierarchyStateChange: { type: Function, required: false }, onShowMenu: { type: Function, required: false }, onHideMenu: { type: Function, required: false }, onIconClick: { type: Function, required: false }, onLegendItemClick: { type: Function, required: false }, onLegendItemHover: { type: Function, required: false }, onLegendItemUnHover: { type: Function, required: false }, onLegendChange: { type: Function, required: false }, onMouseEnterAxis: { type: Function, required: false }, onMouseLeaveAxis: { type: Function, required: false }, onCheckboxStateChange: { type: Function, required: false }, onRadioStateChange: { type: Function, required: false }, onAfterRender: { type: Function, required: false }, onInitialized: { type: Function, required: false }, onPivotSortClick: { type: Function, required: false }, onDrillMenuClick: { type: Function, required: false }, onVChartEventType: { type: Function, required: false }, onChangeCellValue: { type: Function, required: false }, onMousedownFillHandle: { type: Function, required: false }, onDragFillHandleEnd: { type: Function, required: false }, onDblclickFillHandle: { type: Function, required: false }, onScrollVerticalEnd: { type: Function, required: false }, onScrollHorizontalEnd: { type: Function, required: false }, onChangCellValue: { type: Function, required: false }, onEmptyTipClick: { type: Function, required: false }, onEmptyTipDblClick: { type: Function, required: false }, onButtonClick: { type: Function, required: false }, onBeforeCacheChartImage: { type: Function, required: false }, onPastedData: { type: Function, required: false } }, emits: TABLE_EVENTS_KEYS, setup(__props, { expose: __expose, emit: __emit }) { const props = __props; // 创建用于引用 DOM 元素和表格实例的 ref const vTableContainer = ref(null); const vTableInstance = shallowRef(null); // for keepColumnWidthChange const columnWidths = ref(new Map()); const pivotColumnWidths = ref([]); const pivotHeaderColumnWidths = ref([]); // 自定义编辑渲染器 useEditorRender(props, vTableInstance); // 自定义单元格渲染器 useCellRender(props, vTableInstance); // 公开 vTableInstance,以便外部组件可以访问 __expose({ vTableInstance }); // 计算容器的宽度和高度 const containerWidth = computed(() => (typeof props.width === 'number' ? `${props.width}px` : props.width)); const containerHeight = computed(() => (typeof props.height === 'number' ? `${props.height}px` : props.height)); // 绑定事件到表格实例 const emit = __emit; const bindEvents = (instance) => { TABLE_EVENTS_KEYS.forEach(eventKey => { const vueEventHandler = (event) => { emit(eventKey, event); }; instance.on(TABLE_EVENTS[eventKey], vueEventHandler); }); }; const createTableInstance = (Type, options) => { const vtable = new Type(vTableContainer.value, options); vTableInstance.value = vtable; // for keepColumnWidthChange columnWidths.value.clear(); pivotColumnWidths.value = []; pivotHeaderColumnWidths.value = []; vtable.on('resize_column_end', (args) => { // const table = vTableInstance.value; if (!props.keepColumnWidthChange) { return; } const { col, colWidths } = args; const width = colWidths[col]; if (vtable.isPivotTable()) { const path = vtable.getCellHeaderPaths(col, vtable.columnHeaderLevelCount); let dimensions = null; if (path.cellLocation === 'rowHeader') { dimensions = path.rowHeaderPaths; } else { dimensions = path.colHeaderPaths; } let found = false; // pivotColumnWidths.value.forEach(item => { // if (JSON.stringify(item.dimensions) === JSON.stringify(dimensions)) { // item.width = width; // found = true; // } // }); for (let i = 0; i < pivotColumnWidths.value.length; i++) { const item = pivotColumnWidths.value[i]; if (JSON.stringify(item.dimensions) === JSON.stringify(dimensions)) { item.width = width; found = true; } } if (!found) { pivotColumnWidths.value.push({ dimensions, width }); } } else { const define = vtable.getBodyColumnDefine(col, 0); if (define === null || define === void 0 ? void 0 : define.key) { columnWidths.value.set(define.key, width); } } }); }; const createVTable = () => { var _a, _b; if (!vTableContainer.value) { return; } if (vTableInstance.value) { vTableInstance.value.release(); } const getRecords = () => { return props.records !== undefined && props.records !== null && props.records.length > 0 ? props.records : props.options.records; }; try { switch (props.type) { case 'list': createTableInstance(ListTable, Object.assign(Object.assign({}, props.options), { records: getRecords() })); break; case 'pivot': createTableInstance(PivotTable, Object.assign(Object.assign({}, props.options), { records: getRecords() })); break; case 'chart': createTableInstance(PivotChart, Object.assign(Object.assign({}, props.options), { records: getRecords() })); break; } bindEvents(vTableInstance.value); (_a = props.onReady) === null || _a === void 0 ? void 0 : _a.call(props, vTableInstance.value, true); } catch (err) { (_b = props.onError) === null || _b === void 0 ? void 0 : _b.call(props, err); } }; // 更新表格实例 const updateVTable = (newOptions) => { var _a; if (!vTableInstance.value) { return; } try { // for keepColumnWidthChange, update column width if (props.keepColumnWidthChange) { const columnWidthConfig = updateWidthCache(columnWidths.value, pivotColumnWidths.value, vTableInstance.value); newOptions = Object.assign(Object.assign({}, newOptions), { columnWidthConfig: columnWidthConfig, columnWidthConfigForRowHeader: columnWidthConfig }); } switch (props.type) { case 'list': if (vTableInstance.value instanceof ListTable) { vTableInstance.value.updateOption(newOptions); } break; case 'pivot': if (vTableInstance.value instanceof PivotTable) { vTableInstance.value.updateOption(newOptions); } break; case 'chart': if (vTableInstance.value instanceof PivotChart) { vTableInstance.value.updateOption(newOptions); } break; } } catch (err) { (_a = props.onError) === null || _a === void 0 ? void 0 : _a.call(props, err); } }; // 组件挂载时创建表格 onMounted(createVTable); onBeforeUnmount(() => { var _a; (_a = vTableInstance.value) === null || _a === void 0 ? void 0 : _a.release(); }); // 监听 options 属性的变化 // 需要去做细颗粒度的比较 // deep 选中会导致tree失效 watch(() => props.options, (newOptions, oldOptions) => { if (vTableInstance.value) { updateVTable(newOptions); } else { createVTable(); } } // { deep: true }, ); // 监听 records 属性的变化并更新表格 // 需要去做细颗粒度的比较 watch(() => props.records, (newRecords, oldRecords) => { // if (!isEqual(newRecords, oldRecords)) { if (vTableInstance.value) { updateVTable(Object.assign(Object.assign({}, props.options), { records: newRecords })); } else { createVTable(); } // } }, { deep: true }); function updateWidthCache(columnWidths, pivotColumnWidths, table) { if (table.isPivotTable()) { return pivotColumnWidths; } const columnWidthConfig = []; columnWidths.forEach((width, key) => { columnWidthConfig.push({ key, width }); }); return columnWidthConfig; } return (_ctx, _cache) => { return (openBlock(), createElementBlock("div", { ref_key: "vTableContainer", ref: vTableContainer, style: normalizeStyle([{ width: containerWidth.value, height: containerHeight.value }, { "position": "relative" }]) }, null, 4 /* STYLE */)); }; } }); export { _sfc_main as default };