From 80b85732321f363d70662daf0fa6d5635c69a089 Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Fri, 30 Jan 2026 14:27:37 +0800 Subject: [PATCH] =?UTF-8?q?jvxetable=20=E4=BD=BF=E7=94=A8=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E7=9A=84=E6=97=B6=E5=80=99=E5=8D=A1=E9=A1=BF=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20#8695?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jeecg/JVxeTable/src/JVxeTable.ts | 10 +- .../jeecg/JVxeTable/src/hooks/useColumns.ts | 206 ++++++++++-------- .../jeecg/JVxeTable/src/hooks/useData.ts | 158 ++++++++------ .../JVxeTable/src/hooks/useDataSource.ts | 51 +++-- .../JVxeTable/src/hooks/useFinallyProps.ts | 31 ++- .../jeecg/JVxeTable/src/hooks/useMethods.ts | 9 +- 6 files changed, 279 insertions(+), 186 deletions(-) diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/JVxeTable.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/JVxeTable.ts index c1b7d3bdc..e547f3e64 100644 --- a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/JVxeTable.ts +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/JVxeTable.ts @@ -1,4 +1,4 @@ -import { defineComponent, h, nextTick, ref, useSlots } from 'vue'; +import { defineComponent, h, nextTick, useSlots, shallowRef, markRaw } from 'vue'; import { vxeEmits, vxeProps } from './vxe.data'; import { useData, useRefs, useResolveComponent as rc } from './hooks/useData'; import { useColumns } from './hooks/useColumns'; @@ -17,7 +17,10 @@ export default defineComponent({ props: vxeProps(), emits: [...vxeEmits], setup(props: JVxeTableProps, context) { - const instanceRef = ref(); + // 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 refs = useRefs(); const slots = useSlots(); const data = useData(props); @@ -33,6 +36,9 @@ 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, diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts index 9194b572c..77e9fc9bd 100644 --- a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts @@ -1,7 +1,7 @@ import type { JVxeColumn, JVxeDataProps, JVxeTableProps } from '../types'; -import { computed, nextTick, toRaw } from 'vue'; +import { computed, nextTick, toRaw, shallowRef, markRaw } from 'vue'; import { isArray, isEmpty, isPromise } from '/@/utils/is'; -import { cloneDeep } from 'lodash-es'; +import { cloneDeep, debounce } from 'lodash-es'; import { JVxeTypePrefix, JVxeTypes } from '../types/JVxeTypes'; import { initDictOptions } from '/@/utils/dict'; import { pushIfNotExist } from '/@/utils/common/compUtils'; @@ -24,97 +24,129 @@ 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([]); + 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; + } + + const currentHash = getColumnsHash(props.columns); + if (currentHash === lastColumnsHash) { + return; // 列没有变化,直接返回缓存 + } + + lastColumnsHash = currentHash; + const columns: JVxeColumn[] = []; + + // handle 方法参数 + const args: HandleArgs = { props, slots, data, methods, columns }; + let seqColumn, selectionColumn, expandColumn, dragSortColumn; + + const handleColumn = (column: JVxeColumn, container: JVxeColumn[]) => { + // 排除未授权的列 1 = 显示/隐藏; 2 = 禁用 + let auth = methods.getColAuth(column.key); + if (auth?.type == '1' && !auth.isAuth) { + return; + } else if (auth?.type == '2' && !auth.isAuth) { + column.disabled = true; + } + // type 不填,默认为 normal + if (column.type == null || isEmpty(column.type)) { + column.type = JVxeTypes.normal; + } + let col: JVxeColumn = cloneDeep(column); + // 处理隐藏列 + if (col.type === JVxeTypes.hidden) { + return handleInnerColumn(args, col, handleHiddenColumn); + } + // 处理子级列 + // 判断是否是分组列,如果当前是父级,则无需处理 render + if (Array.isArray(col.children) && col.children.length > 0) { + const children: JVxeColumn[] = []; + col.children.forEach((child: JVxeColumn) => handleColumn(child, children)); + col.children = children; + container.push(col); + return; + } + // 组件未注册,自动设置为 normal + if (!isRegistered(col.type)) { + col.type = JVxeTypes.normal; + } + args.enhanced = getEnhanced(col.type); + args.col = col; + args.renderOptions = { + bordered: props.bordered, + disabled: props.disabled, + scrolling: data.scrolling, + isDisabledRow: methods.isDisabledRow, + listeners: { + trigger: (name, event) => methods.trigger(name, event), + valueChange: (event) => methods.trigger('valueChange', event), + /** 重新排序行 */ + rowResort: (event) => { + methods.doSort(event.oldIndex, event.newIndex); + methods.trigger('dragged', event); + }, + /** 在当前行下面插入一行 */ + rowInsertDown: (rowIndex) => methods.insertRows({}, rowIndex + 1), + }, + }; + if (col.type === JVxeTypes.rowNumber) { + seqColumn = col; + container.push(col); + } else if (col.type === JVxeTypes.rowRadio || col.type === JVxeTypes.rowCheckbox) { + selectionColumn = col; + container.push(col); + } else if (col.type === JVxeTypes.rowExpand) { + expandColumn = col; + container.push(col); + } else if (col.type === JVxeTypes.rowDragSort) { + dragSortColumn = col; + container.push(col); + } else { + col.params = column; + args.columns = container; + handlerCol(args); + } + } + + props.columns.forEach((column: JVxeColumn) => handleColumn(column, columns)); + + handleInnerColumn(args, seqColumn, handleSeqColumn); + handleInnerColumn(args, selectionColumn, handleSelectionColumn); + handleInnerColumn(args, expandColumn, handleExpandColumn); + 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(() => { - // linkageConfig变化时也需要执行 + // 【issues/7812】linkageConfig改变了,vxetable没更新 + // linkageConfig变化时也需要执行 const linkageConfig = toRaw(props.linkageConfig); if (linkageConfig) { // console.log(linkageConfig); } - let columns: JVxeColumn[] = []; - if (isArray(props.columns)) { - // handle 方法参数 - const args: HandleArgs = { props, slots, data, methods, columns }; - let seqColumn, selectionColumn, expandColumn, dragSortColumn; - - const handleColumn = (column: JVxeColumn, container: JVxeColumn[]) => { - // 排除未授权的列 1 = 显示/隐藏; 2 = 禁用 - let auth = methods.getColAuth(column.key); - if (auth?.type == '1' && !auth.isAuth) { - return; - } else if (auth?.type == '2' && !auth.isAuth) { - column.disabled = true; - } - // type 不填,默认为 normal - if (column.type == null || isEmpty(column.type)) { - column.type = JVxeTypes.normal; - } - let col: JVxeColumn = cloneDeep(column); - // 处理隐藏列 - if (col.type === JVxeTypes.hidden) { - return handleInnerColumn(args, col, handleHiddenColumn); - } - // 处理子级列 - // 判断是否是分组列,如果当前是父级,则无需处理 render - if (Array.isArray(col.children) && col.children.length > 0) { - const children: JVxeColumn[] = []; - col.children.forEach((child: JVxeColumn) => handleColumn(child, children)); - col.children = children; - container.push(col); - return; - } - // 组件未注册,自动设置为 normal - if (!isRegistered(col.type)) { - col.type = JVxeTypes.normal; - } - args.enhanced = getEnhanced(col.type); - args.col = col; - args.renderOptions = { - bordered: props.bordered, - disabled: props.disabled, - scrolling: data.scrolling, - isDisabledRow: methods.isDisabledRow, - listeners: { - trigger: (name, event) => methods.trigger(name, event), - valueChange: (event) => methods.trigger('valueChange', event), - /** 重新排序行 */ - rowResort: (event) => { - methods.doSort(event.oldIndex, event.newIndex); - methods.trigger('dragged', event); - }, - /** 在当前行下面插入一行 */ - rowInsertDown: (rowIndex) => methods.insertRows({}, rowIndex + 1), - }, - }; - if (col.type === JVxeTypes.rowNumber) { - seqColumn = col; - container.push(col); - } else if (col.type === JVxeTypes.rowRadio || col.type === JVxeTypes.rowCheckbox) { - selectionColumn = col; - container.push(col); - } else if (col.type === JVxeTypes.rowExpand) { - expandColumn = col; - container.push(col); - } else if (col.type === JVxeTypes.rowDragSort) { - dragSortColumn = col; - container.push(col); - } else { - col.params = column; - args.columns = container; - handlerCol(args); - } - } - - props.columns.forEach((column: JVxeColumn) => handleColumn(column, columns)); - - handleInnerColumn(args, seqColumn, handleSeqColumn); - handleInnerColumn(args, selectionColumn, handleSelectionColumn); - handleInnerColumn(args, expandColumn, handleExpandColumn); - handleInnerColumn(args, dragSortColumn, handleDragSortColumn, true); - // update-begin--author:liaozhiyang---date:2024-05-30---for【TV360X-371】不可编辑组件必填缺少*号 - customComponentAddStar(columns); - } - return columns; + // 触发防抖计算 + debouncedComputeColumns(); + return columnsCache.value; }); + // update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 } /** diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useData.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useData.ts index 474a13ae4..cd79b3203 100644 --- a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useData.ts +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useData.ts @@ -1,4 +1,4 @@ -import { ref, reactive, provide, resolveComponent } from 'vue'; +import { ref, reactive, provide, resolveComponent, shallowRef, markRaw } from 'vue'; import { useDesign } from '/@/hooks/web/useDesign'; import { JVxeDataProps, JVxeRefs, JVxeTableProps } from '../types'; import { VxeGridInstance } from 'vxe-table'; @@ -7,90 +7,108 @@ 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警告 + // 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 + showOverflow: "title", + // 表头溢出隐藏并显示tooltip + showHeaderOverflow: "title", + // --- 【issues/209】自带的tooltip会错位,所以替换成原生的title --- + + showFooterOverflow: true, + // 可编辑配置 + 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', + iconOpen: 'vxe-icon-arrow-down', + ...props.expandConfig, + }, + // 虚拟滚动配置,y轴大于xx条数据时启用虚拟滚动 + scrollY: { + gt: 30, + }, + scrollX: { + gt: 20, + // 暂时关闭左右虚拟滚动 + enabled: false, + }, + radioConfig: { + // 保留勾选状态 + reserve: true, + highlight: true, + }, + checkboxConfig: { + // 保留勾选状态 + reserve: true, + highlight: true, + }, + mouseConfig: { selected: false }, + keyboardConfig: { + // 删除键功能 + isDel: false, + // Esc键关闭编辑功能 + isEsc: true, + // Tab 键功能 + isTab: true, + // 任意键进入编辑(功能键除外) + isEdit: true, + // 方向键功能 + isArrow: true, + // 回车键功能 + isEnter: true, + // 如果功能被支持,用于 column.type=checkbox|radio,开启空格键切换复选框或单选框状态功能 + isChecked: true, + }, + }); + + // 使用 shallowRef 优化选中行性能 + const selectedRows = shallowRef([]); + const selectedRowIds = shallowRef([]); + const authsMap = shallowRef(null); + return { prefixCls: prefixCls, caseId: `j-vxe-${randomString(8)}`, - vxeDataSource: ref([]), + vxeDataSource, scroll: reactive({ top: 0, left: 0 }), scrolling: ref(false), - defaultVxeProps: reactive({ - // rowId: props.rowKey, - rowConfig: { - keyField: props.rowKey, - // 高亮hover的行 - isHover: true, - }, - - // --- 【issues/209】自带的tooltip会错位,所以替换成原生的title --- - // 溢出隐藏并显示tooltip - showOverflow: "title", - // 表头溢出隐藏并显示tooltip - showHeaderOverflow: "title", - // --- 【issues/209】自带的tooltip会错位,所以替换成原生的title --- - - showFooterOverflow: true, - // 可编辑配置 - editConfig: { - trigger: 'click', - mode: 'cell', - //activeMethod: () => !props.disabled, - beforeEditMethod: () => !props.disabled, - }, - expandConfig: { - iconClose: 'vxe-icon-arrow-right', - iconOpen: 'vxe-icon-arrow-down', - ...props.expandConfig, - }, - // 虚拟滚动配置,y轴大于xx条数据时启用虚拟滚动 - scrollY: { - gt: 30, - }, - scrollX: { - gt: 20, - // 暂时关闭左右虚拟滚动 - enabled: false, - }, - radioConfig: { - // 保留勾选状态 - reserve: true, - highlight: true, - }, - checkboxConfig: { - // 保留勾选状态 - reserve: true, - highlight: true, - }, - mouseConfig: { selected: false }, - keyboardConfig: { - // 删除键功能 - isDel: false, - // Esc键关闭编辑功能 - isEsc: true, - // Tab 键功能 - isTab: true, - // 任意键进入编辑(功能键除外) - isEdit: true, - // 方向键功能 - isArrow: true, - // 回车键功能 - isEnter: true, - // 如果功能被支持,用于 column.type=checkbox|radio,开启空格键切换复选框或单选框状态功能 - isChecked: true, - }, - }), - selectedRows: ref([]), - selectedRowIds: ref([]), + defaultVxeProps, + selectedRows, + selectedRowIds, disabledRowIds: [], statistics: reactive({ has: false, sum: [], average: [], }), - authsMap: ref(null), + authsMap, innerEditRules: {}, innerLinkageConfig: new Map(), reloadEffectRowKeysMap: reactive({}), }; + // update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 } export function useRefs(): JVxeRefs { diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useDataSource.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useDataSource.ts index 3810e539f..74b7b8cd0 100644 --- a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useDataSource.ts +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useDataSource.ts @@ -1,36 +1,55 @@ import { nextTick, watch } from 'vue'; import { JVxeDataProps, JVxeRefs, JVxeTableMethods } from '../types'; -import { cloneDeep } from 'lodash-es'; +import { cloneDeep, debounce } from 'lodash-es'; export function useDataSource(props, data: JVxeDataProps, methods: JVxeTableMethods, refs: JVxeRefs) { + // update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 + // 使用浅拷贝优化大数据量处理 + const processDataSource = debounce(async (newDataSource) => { + if (!Array.isArray(newDataSource)) { + data.vxeDataSource.value = []; + return; + } + data.vxeDataSource.value = cloneDeep(newDataSource); + // 批量处理禁用行,减少循环次数 + const disabledRowIds: string[] = []; + data.vxeDataSource.value.forEach((row, rowIndex) => { + // 判断是否是禁用行 + if (methods.isDisabledRow(row, rowIndex)) { + disabledRowIds.push(row.id); + } + // 处理联动回显数据 + methods.handleLinkageBackData(row); + }); + data.disabledRowIds = disabledRowIds; + + const grid = await waitRef(refs.gridRef); + if (grid?.value) methods.recalcSortNumber(); + }, 50); // 50ms 防抖,避免频繁更新 + watch( () => props.dataSource, - async () => { - data.disabledRowIds = []; - data.vxeDataSource.value = cloneDeep(props.dataSource); - data.vxeDataSource.value.forEach((row, rowIndex) => { - // 判断是否是禁用行 - if (methods.isDisabledRow(row, rowIndex)) { - data.disabledRowIds.push(row.id); - } - // 处理联动回显数据 - methods.handleLinkageBackData(row); - }); - await waitRef(refs.gridRef); - methods.recalcSortNumber(); + (newDataSource) => { + processDataSource(newDataSource); }, { immediate: true } ); + // update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 } - -function waitRef($ref) { +// update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 +function waitRef($ref, maxTries = 10) { return new Promise((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配置界面,字段配置卡顿 diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useFinallyProps.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useFinallyProps.ts index 90351ef3e..4a7bf9ad5 100644 --- a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useFinallyProps.ts +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useFinallyProps.ts @@ -1,5 +1,5 @@ -import { unref, computed, ref, watch, nextTick } from 'vue'; -import { merge, debounce } from 'lodash-es'; +import { unref, computed, ref, watch, nextTick, shallowRef } from 'vue'; +import { merge, debounce, throttle } from 'lodash-es'; import { isArray } from '/@/utils/is'; import { useAttrs } from '/@/hooks/core/useAttrs'; import { useKeyboardEdit } from '../hooks/useKeyboardEdit'; @@ -11,12 +11,19 @@ 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 = { - onScroll: methods.handleVxeScroll, - onCellClick: methods.handleCellClick, + // update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 + onScroll: throttledScroll, + onCellClick: throttledCellClick, + // update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 onEditClosed: methods.handleEditClosed, onEditActived: methods.handleEditActived, onRadioChange: methods.handleVxeRadioChange, @@ -111,14 +118,20 @@ export function useFinallyProps(props: JVxeTableProps, data: JVxeDataProps, meth ); }); - // 代码逻辑说明: 【issues/8593】修复列改变后内容不刷新 - const vxeColumnsRef = ref(data.vxeColumns!.value || []) + // update-begin--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 + // 使用 shallowRef 优化列更新性能 + const vxeColumnsRef = shallowRef([]) const watchColumnsDebounce = debounce(async () => { vxeColumnsRef.value = [] await nextTick() - vxeColumnsRef.value = data.vxeColumns!.value - }, 50) - watch(data.vxeColumns!, watchColumnsDebounce) + vxeColumnsRef.value = data.vxeColumns?.value || [] + }, 16) // 减少防抖时间到16ms,提高响应速度 + + // 安全地监听列变化 + if (data.vxeColumns) { + watch(data.vxeColumns, watchColumnsDebounce) + } + // update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿 const vxeProps = computed(() => { return { diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useMethods.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useMethods.ts index b728ccd94..7f3c118f2 100644 --- a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useMethods.ts +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useMethods.ts @@ -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 } from 'lodash-es'; +import { cloneDeep, throttle } 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滚动条位置 */ - function handleVxeScroll(event) { + const throttledScroll = throttle((event) => { let { scroll } = data; // 记录滚动条的位置 @@ -77,7 +77,12 @@ 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) {