mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-02-05 01:55:29 +08:00
暂时回滚JVxeTable性能优化,有严重bug
This commit is contained in:
@ -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,
|
||||
|
||||
@ -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配置界面,字段配置卡顿
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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配置界面,字段配置卡顿
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user