暂时回滚JVxeTable性能优化,有严重bug

This commit is contained in:
JEECG 2026-02-03 17:18:34 +08:00
parent 05caace985
commit 04a26cdd6d
6 changed files with 172 additions and 251 deletions

View File

@ -1,4 +1,4 @@
import { defineComponent, h, nextTick, useSlots, shallowRef, markRaw } from 'vue'; import { defineComponent, h, nextTick, ref, useSlots } from 'vue';
import { vxeEmits, vxeProps } from './vxe.data'; import { vxeEmits, vxeProps } from './vxe.data';
import { useData, useRefs, useResolveComponent as rc } from './hooks/useData'; import { useData, useRefs, useResolveComponent as rc } from './hooks/useData';
import { useColumns } from './hooks/useColumns'; import { useColumns } from './hooks/useColumns';
@ -17,10 +17,7 @@ export default defineComponent({
props: vxeProps(), props: vxeProps(),
emits: [...vxeEmits], emits: [...vxeEmits],
setup(props: JVxeTableProps, context) { setup(props: JVxeTableProps, context) {
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online const instanceRef = ref();
// 使 shallowRef
const instanceRef = shallowRef();
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online
const refs = useRefs(); const refs = useRefs();
const slots = useSlots(); const slots = useSlots();
const data = useData(props); const data = useData(props);
@ -36,9 +33,6 @@ export default defineComponent({
const finallyProps = useFinallyProps(props, data, methods); const finallyProps = useFinallyProps(props, data, methods);
// //
const renderComponents = useRenderComponents(props, data, methods, slots); const renderComponents = useRenderComponents(props, data, methods, slots);
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online
markRaw(renderComponents);
// update-end--author:liaozhiyang---date:20260130---for:QQYUN-14177online
return { return {
instanceRef, instanceRef,
...refs, ...refs,

View File

@ -1,7 +1,7 @@
import type { JVxeColumn, JVxeDataProps, JVxeTableProps } from '../types'; import type { JVxeColumn, JVxeDataProps, JVxeTableProps } from '../types';
import { computed, nextTick, toRaw, shallowRef, markRaw } from 'vue'; import { computed, nextTick, toRaw } from 'vue';
import { isArray, isEmpty, isPromise } from '/@/utils/is'; import { isArray, isEmpty, isPromise } from '/@/utils/is';
import { cloneDeep, debounce } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import { JVxeTypePrefix, JVxeTypes } from '../types/JVxeTypes'; import { JVxeTypePrefix, JVxeTypes } from '../types/JVxeTypes';
import { initDictOptions } from '/@/utils/dict'; import { initDictOptions } from '/@/utils/dict';
import { pushIfNotExist } from '/@/utils/common/compUtils'; import { pushIfNotExist } from '/@/utils/common/compUtils';
@ -24,31 +24,14 @@ export interface HandleArgs {
} }
export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods: JVxeTableMethods, slots) { export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods: JVxeTableMethods, slots) {
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online data.vxeColumns = computed(() => {
// 使 shallowRef // linkageConfig
const columnsCache = shallowRef<JVxeColumn[]>([]); const linkageConfig = toRaw(props.linkageConfig);
let lastColumnsHash = ''; if (linkageConfig) {
// console.log(linkageConfig);
//
const getColumnsHash = (columns: JVxeColumn[]) => {
return JSON.stringify(columns.map(col => ({ key: col.key, type: col.type, title: col.title })));
};
//
const debouncedComputeColumns = debounce(() => {
if (!isArray(props.columns)) {
columnsCache.value = [];
return;
} }
let columns: JVxeColumn[] = [];
const currentHash = getColumnsHash(props.columns); if (isArray(props.columns)) {
if (currentHash === lastColumnsHash) {
return; //
}
lastColumnsHash = currentHash;
const columns: JVxeColumn[] = [];
// handle // handle
const args: HandleArgs = { props, slots, data, methods, columns }; const args: HandleArgs = { props, slots, data, methods, columns };
let seqColumn, selectionColumn, expandColumn, dragSortColumn; let seqColumn, selectionColumn, expandColumn, dragSortColumn;
@ -129,24 +112,9 @@ export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods:
handleInnerColumn(args, dragSortColumn, handleDragSortColumn, true); handleInnerColumn(args, dragSortColumn, handleDragSortColumn, true);
// update-begin--author:liaozhiyang---date:2024-05-30---forTV360X-371* // update-begin--author:liaozhiyang---date:2024-05-30---forTV360X-371*
customComponentAddStar(columns); customComponentAddStar(columns);
// update-end--author:liaozhiyang---date:2024-05-30---forTV360X-371*
//
columnsCache.value = markRaw(columns);
}, 16); // 16ms
data.vxeColumns = computed(() => {
// issues/7812linkageConfigvxetable
// linkageConfig
const linkageConfig = toRaw(props.linkageConfig);
if (linkageConfig) {
// console.log(linkageConfig);
} }
// return columns;
debouncedComputeColumns();
return columnsCache.value;
}); });
// update-end--author:liaozhiyang---date:20260130---for:QQYUN-14177online
} }
/** /**

View File

@ -1,4 +1,4 @@
import { ref, reactive, provide, resolveComponent, shallowRef, markRaw } from 'vue'; import { ref, reactive, provide, resolveComponent } from 'vue';
import { useDesign } from '/@/hooks/web/useDesign'; import { useDesign } from '/@/hooks/web/useDesign';
import { JVxeDataProps, JVxeRefs, JVxeTableProps } from '../types'; import { JVxeDataProps, JVxeRefs, JVxeTableProps } from '../types';
import { VxeGridInstance } from 'vxe-table'; import { VxeGridInstance } from 'vxe-table';
@ -7,21 +7,19 @@ import { randomString } from '/@/utils/common/compUtils';
export function useData(props: JVxeTableProps): JVxeDataProps { export function useData(props: JVxeTableProps): JVxeDataProps {
const { prefixCls } = useDesign('j-vxe-table'); const { prefixCls } = useDesign('j-vxe-table');
provide('prefixCls', prefixCls); provide('prefixCls', prefixCls);
return {
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online prefixCls: prefixCls,
// 使 shallowRef caseId: `j-vxe-${randomString(8)}`,
const vxeDataSource = shallowRef([]); vxeDataSource: ref([]),
scroll: reactive({ top: 0, left: 0 }),
// scrolling: ref(false),
const defaultVxeProps = markRaw({ defaultVxeProps: reactive({
// update-begin--author:liaozhiyang---date:20240607---forTV360X-327vxetable
// rowId: props.rowKey, // rowId: props.rowKey,
rowConfig: { rowConfig: {
keyField: props.rowKey, keyField: props.rowKey,
// hover // hover
isHover: true, isHover: true,
}, },
// update-end--author:liaozhiyang---date:20240607---forTV360X-327vxetable
// --- issues/209tooltiptitle --- // --- issues/209tooltiptitle ---
// tooltip // tooltip
@ -35,10 +33,8 @@ export function useData(props: JVxeTableProps): JVxeDataProps {
editConfig: { editConfig: {
trigger: 'click', trigger: 'click',
mode: 'cell', mode: 'cell',
// update-begin--author:liaozhiyang---date:20231013---forQQYUN-5133JVxeTable
//activeMethod: () => !props.disabled, //activeMethod: () => !props.disabled,
beforeEditMethod: () => !props.disabled, beforeEditMethod: () => !props.disabled,
// update-end--author:liaozhiyang---date:20231013---forQQYUN-5133JVxeTable
}, },
expandConfig: { expandConfig: {
iconClose: 'vxe-icon-arrow-right', iconClose: 'vxe-icon-arrow-right',
@ -81,34 +77,20 @@ export function useData(props: JVxeTableProps): JVxeDataProps {
// column.type=checkbox|radio // column.type=checkbox|radio
isChecked: true, isChecked: true,
}, },
}); }),
selectedRows: ref<any[]>([]),
// 使 shallowRef selectedRowIds: ref<string[]>([]),
const selectedRows = shallowRef<any[]>([]);
const selectedRowIds = shallowRef<string[]>([]);
const authsMap = shallowRef(null);
return {
prefixCls: prefixCls,
caseId: `j-vxe-${randomString(8)}`,
vxeDataSource,
scroll: reactive({ top: 0, left: 0 }),
scrolling: ref(false),
defaultVxeProps,
selectedRows,
selectedRowIds,
disabledRowIds: [], disabledRowIds: [],
statistics: reactive({ statistics: reactive({
has: false, has: false,
sum: [], sum: [],
average: [], average: [],
}), }),
authsMap, authsMap: ref(null),
innerEditRules: {}, innerEditRules: {},
innerLinkageConfig: new Map<string, any>(), innerLinkageConfig: new Map<string, any>(),
reloadEffectRowKeysMap: reactive({}), reloadEffectRowKeysMap: reactive({}),
}; };
// update-end--author:liaozhiyang---date:20260130---for:QQYUN-14177online
} }
export function useRefs(): JVxeRefs { export function useRefs(): JVxeRefs {

View File

@ -22,20 +22,15 @@ export function useDataSource(props, data: JVxeDataProps, methods: JVxeTableMeth
{ immediate: true } { immediate: true }
); );
} }
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online
function waitRef($ref, maxTries = 100) { function waitRef($ref) {
return new Promise<any>((resolve) => { return new Promise<any>((resolve) => {
let tries = 0;
(function next() { (function next() {
if ($ref.value) { if ($ref.value) {
resolve($ref); resolve($ref);
} else if (tries >= maxTries) {
resolve(null);
} else { } else {
tries++;
nextTick(() => next()); nextTick(() => next());
} }
})(); })();
}); });
} }
// update-end--author:liaozhiyang---date:20260130---for:QQYUN-14177online

View File

@ -1,5 +1,5 @@
import { unref, computed, ref, watch, nextTick, shallowRef } from 'vue'; import { unref, computed, ref, watch, nextTick } from 'vue';
import { merge, debounce, throttle } from 'lodash-es'; import { merge, debounce } from 'lodash-es';
import { isArray } from '/@/utils/is'; import { isArray } from '/@/utils/is';
import { useAttrs } from '/@/hooks/core/useAttrs'; import { useAttrs } from '/@/hooks/core/useAttrs';
import { useKeyboardEdit } from '../hooks/useKeyboardEdit'; import { useKeyboardEdit } from '../hooks/useKeyboardEdit';
@ -11,19 +11,12 @@ export function useFinallyProps(props: JVxeTableProps, data: JVxeDataProps, meth
const { keyboardEditConfig } = useKeyboardEdit(props); const { keyboardEditConfig } = useKeyboardEdit(props);
// vxe editRules // vxe editRules
const vxeEditRules = computed(() => merge({}, props.editRules, data.innerEditRules)); const vxeEditRules = computed(() => merge({}, props.editRules, data.innerEditRules));
// ==================== - ====================
// 使
const throttledScroll = throttle(methods.handleVxeScroll, 16); // 60fps
const throttledCellClick = throttle(methods.handleCellClick, 100);
// vxe events // vxe events
const vxeEvents = computed(() => { const vxeEvents = computed(() => {
let listeners = { ...unref(attrs) }; let listeners = { ...unref(attrs) };
let events = { let events = {
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online onScroll: methods.handleVxeScroll,
onScroll: throttledScroll, onCellClick: methods.handleCellClick,
onCellClick: throttledCellClick,
// update-end--author:liaozhiyang---date:20260130---for:QQYUN-14177online
onEditClosed: methods.handleEditClosed, onEditClosed: methods.handleEditClosed,
onEditActived: methods.handleEditActived, onEditActived: methods.handleEditActived,
onRadioChange: methods.handleVxeRadioChange, onRadioChange: methods.handleVxeRadioChange,
@ -118,20 +111,14 @@ export function useFinallyProps(props: JVxeTableProps, data: JVxeDataProps, meth
); );
}); });
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online // : issues/8593
// 使 shallowRef const vxeColumnsRef = ref(data.vxeColumns!.value || [])
const vxeColumnsRef = shallowRef([])
const watchColumnsDebounce = debounce(async () => { const watchColumnsDebounce = debounce(async () => {
vxeColumnsRef.value = [] vxeColumnsRef.value = []
await nextTick() await nextTick()
vxeColumnsRef.value = data.vxeColumns?.value || [] vxeColumnsRef.value = data.vxeColumns!.value
}, 16) // 16ms }, 50)
watch(data.vxeColumns!, watchColumnsDebounce)
//
if (data.vxeColumns) {
watch(data.vxeColumns, watchColumnsDebounce)
}
// update-end--author:liaozhiyang---date:20260130---for:QQYUN-14177online
const vxeProps = computed(() => { const vxeProps = computed(() => {
return { return {

View File

@ -4,7 +4,7 @@ import { simpleDebounce } from '/@/utils/common/compUtils';
import { JVxeDataProps, JVxeRefs, JVxeTableProps, JVxeTypes } from '../types'; import { JVxeDataProps, JVxeRefs, JVxeTableProps, JVxeTypes } from '../types';
import { getEnhanced } from '../utils/enhancedUtils'; import { getEnhanced } from '../utils/enhancedUtils';
import { VxeTableInstance, VxeTablePrivateMethods } from 'vxe-table'; import { VxeTableInstance, VxeTablePrivateMethods } from 'vxe-table';
import { cloneDeep, throttle } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import { isArray, isEmpty, isNull, isString } from '/@/utils/is'; import { isArray, isEmpty, isNull, isString } from '/@/utils/is';
import { useLinkage } from './useLinkage'; import { useLinkage } from './useLinkage';
import { useWebSocket } from './useWebSocket'; import { useWebSocket } from './useWebSocket';
@ -67,7 +67,7 @@ export function useMethods(props: JVxeTableProps, { emit }, data: JVxeDataProps,
}; };
/** 监听vxe滚动条位置 */ /** 监听vxe滚动条位置 */
const throttledScroll = throttle((event) => { function handleVxeScroll(event) {
let { scroll } = data; let { scroll } = data;
// //
@ -77,12 +77,7 @@ export function useMethods(props: JVxeTableProps, { emit }, data: JVxeDataProps,
refs.subPopoverRef.value?.close(); refs.subPopoverRef.value?.close();
data.scrolling.value = true; data.scrolling.value = true;
closeScrolling(); closeScrolling();
}, 16);
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online
function handleVxeScroll(event) {
throttledScroll(event);
} }
// update-begin--author:liaozhiyang---date:20260130---for:QQYUN-14177online
// //
function handleVxeRadioChange(event) { function handleVxeRadioChange(event) {