暂时回滚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 { useData, useRefs, useResolveComponent as rc } from './hooks/useData';
import { useColumns } from './hooks/useColumns';
@ -17,10 +17,7 @@ export default defineComponent({
props: vxeProps(),
emits: [...vxeEmits],
setup(props: JVxeTableProps, context) {
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
// 使用 shallowRef 优化大型对象响应式性能
const instanceRef = shallowRef();
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
const instanceRef = ref();
const refs = useRefs();
const slots = useSlots();
const data = useData(props);
@ -36,9 +33,6 @@ export default defineComponent({
const finallyProps = useFinallyProps(props, data, methods);
// 渲染子组件
const renderComponents = useRenderComponents(props, data, methods, slots);
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
markRaw(renderComponents);
// update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
return {
instanceRef,
...refs,

View File

@ -1,7 +1,7 @@
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 { cloneDeep, debounce } from 'lodash-es';
import { cloneDeep } from 'lodash-es';
import { JVxeTypePrefix, JVxeTypes } from '../types/JVxeTypes';
import { initDictOptions } from '/@/utils/dict';
import { pushIfNotExist } from '/@/utils/common/compUtils';
@ -24,31 +24,14 @@ export interface HandleArgs {
}
export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods: JVxeTableMethods, slots) {
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
// 使用 shallowRef 优化列数据响应式性能
const columnsCache = shallowRef<JVxeColumn[]>([]);
let lastColumnsHash = '';
// 计算列哈希值,用于缓存判断
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;
data.vxeColumns = computed(() => {
// linkageConfig变化时也需要执行
const linkageConfig = toRaw(props.linkageConfig);
if (linkageConfig) {
// console.log(linkageConfig);
}
const currentHash = getColumnsHash(props.columns);
if (currentHash === lastColumnsHash) {
return; // 列没有变化,直接返回缓存
}
lastColumnsHash = currentHash;
const columns: JVxeColumn[] = [];
let columns: JVxeColumn[] = [];
if (isArray(props.columns)) {
// handle 方法参数
const args: HandleArgs = { props, slots, data, methods, columns };
let seqColumn, selectionColumn, expandColumn, dragSortColumn;
@ -129,24 +112,9 @@ export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods:
handleInnerColumn(args, dragSortColumn, handleDragSortColumn, true);
// update-begin--author:liaozhiyang---date:2024-05-30---for【TV360X-371】不可编辑组件必填缺少*号
customComponentAddStar(columns);
// update-end--author:liaozhiyang---date:2024-05-30---for【TV360X-371】不可编辑组件必填缺少*号
// 标记为原始对象,避免深度响应式
columnsCache.value = markRaw(columns);
}, 16); // 16ms 防抖,约等于一帧的时间
data.vxeColumns = computed(() => {
// 【issues/7812】linkageConfig改变了vxetable没更新
// linkageConfig变化时也需要执行
const linkageConfig = toRaw(props.linkageConfig);
if (linkageConfig) {
// console.log(linkageConfig);
}
// 触发防抖计算
debouncedComputeColumns();
return columnsCache.value;
return columns;
});
// update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
}
/**

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 { JVxeDataProps, JVxeRefs, JVxeTableProps } from '../types';
import { VxeGridInstance } from 'vxe-table';
@ -7,21 +7,19 @@ import { randomString } from '/@/utils/common/compUtils';
export function useData(props: JVxeTableProps): JVxeDataProps {
const { prefixCls } = useDesign('j-vxe-table');
provide('prefixCls', prefixCls);
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
// 使用 shallowRef 优化大数据源性能
const vxeDataSource = shallowRef([]);
// 标记静态配置对象,避免深度响应式
const defaultVxeProps = markRaw({
// update-begin--author:liaozhiyang---date:20240607---for【TV360X-327】vxetable警告
return {
prefixCls: prefixCls,
caseId: `j-vxe-${randomString(8)}`,
vxeDataSource: ref([]),
scroll: reactive({ top: 0, left: 0 }),
scrolling: ref(false),
defaultVxeProps: reactive({
// rowId: props.rowKey,
rowConfig: {
keyField: props.rowKey,
// 高亮hover的行
isHover: true,
},
// update-end--author:liaozhiyang---date:20240607---for【TV360X-327】vxetable警告
// --- 【issues/209】自带的tooltip会错位所以替换成原生的title ---
// 溢出隐藏并显示tooltip
@ -35,10 +33,8 @@ export function useData(props: JVxeTableProps): JVxeDataProps {
editConfig: {
trigger: 'click',
mode: 'cell',
// update-begin--author:liaozhiyang---date:20231013---for【QQYUN-5133】JVxeTable 行编辑升级
//activeMethod: () => !props.disabled,
beforeEditMethod: () => !props.disabled,
// update-end--author:liaozhiyang---date:20231013---for【QQYUN-5133】JVxeTable 行编辑升级
},
expandConfig: {
iconClose: 'vxe-icon-arrow-right',
@ -81,34 +77,20 @@ export function useData(props: JVxeTableProps): JVxeDataProps {
// 如果功能被支持,用于 column.type=checkbox|radio开启空格键切换复选框或单选框状态功能
isChecked: true,
},
});
// 使用 shallowRef 优化选中行性能
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,
}),
selectedRows: ref<any[]>([]),
selectedRowIds: ref<string[]>([]),
disabledRowIds: [],
statistics: reactive({
has: false,
sum: [],
average: [],
}),
authsMap,
authsMap: ref(null),
innerEditRules: {},
innerLinkageConfig: new Map<string, any>(),
reloadEffectRowKeysMap: reactive({}),
};
// update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
}
export function useRefs(): JVxeRefs {

View File

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

View File

@ -1,5 +1,5 @@
import { unref, computed, ref, watch, nextTick, shallowRef } from 'vue';
import { merge, debounce, throttle } from 'lodash-es';
import { unref, computed, ref, watch, nextTick } from 'vue';
import { merge, debounce } from 'lodash-es';
import { isArray } from '/@/utils/is';
import { useAttrs } from '/@/hooks/core/useAttrs';
import { useKeyboardEdit } from '../hooks/useKeyboardEdit';
@ -11,19 +11,12 @@ export function useFinallyProps(props: JVxeTableProps, data: JVxeDataProps, meth
const { keyboardEditConfig } = useKeyboardEdit(props);
// vxe 最终 editRules
const vxeEditRules = computed(() => merge({}, props.editRules, data.innerEditRules));
// ==================== 性能优化 - 开始 ====================
// 使用节流优化高频事件
const throttledScroll = throttle(methods.handleVxeScroll, 16); // 约60fps
const throttledCellClick = throttle(methods.handleCellClick, 100);
// vxe 最终 events
const vxeEvents = computed(() => {
let listeners = { ...unref(attrs) };
let events = {
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
onScroll: throttledScroll,
onCellClick: throttledCellClick,
// update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
onScroll: methods.handleVxeScroll,
onCellClick: methods.handleCellClick,
onEditClosed: methods.handleEditClosed,
onEditActived: methods.handleEditActived,
onRadioChange: methods.handleVxeRadioChange,
@ -118,20 +111,14 @@ export function useFinallyProps(props: JVxeTableProps, data: JVxeDataProps, meth
);
});
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
// 使用 shallowRef 优化列更新性能
const vxeColumnsRef = shallowRef([])
// 代码逻辑说明: 【issues/8593】修复列改变后内容不刷新
const vxeColumnsRef = ref(data.vxeColumns!.value || [])
const watchColumnsDebounce = debounce(async () => {
vxeColumnsRef.value = []
await nextTick()
vxeColumnsRef.value = data.vxeColumns?.value || []
}, 16) // 减少防抖时间到16ms提高响应速度
// 安全地监听列变化
if (data.vxeColumns) {
watch(data.vxeColumns, watchColumnsDebounce)
}
// update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
vxeColumnsRef.value = data.vxeColumns!.value
}, 50)
watch(data.vxeColumns!, watchColumnsDebounce)
const vxeProps = computed(() => {
return {

View File

@ -4,7 +4,7 @@ import { simpleDebounce } from '/@/utils/common/compUtils';
import { JVxeDataProps, JVxeRefs, JVxeTableProps, JVxeTypes } from '../types';
import { getEnhanced } from '../utils/enhancedUtils';
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 { useLinkage } from './useLinkage';
import { useWebSocket } from './useWebSocket';
@ -67,7 +67,7 @@ export function useMethods(props: JVxeTableProps, { emit }, data: JVxeDataProps,
};
/** 监听vxe滚动条位置 */
const throttledScroll = throttle((event) => {
function handleVxeScroll(event) {
let { scroll } = data;
// 记录滚动条的位置
@ -77,12 +77,7 @@ export function useMethods(props: JVxeTableProps, { emit }, data: JVxeDataProps,
refs.subPopoverRef.value?.close();
data.scrolling.value = true;
closeScrolling();
}, 16);
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
function handleVxeScroll(event) {
throttledScroll(event);
}
// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面字段配置卡顿
// 当手动勾选单选时触发的事件
function handleVxeRadioChange(event) {