mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-01-30 23:27:01 +08:00
jvxetable 使用编辑的时候卡顿问题 #8695
This commit is contained in:
@ -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,
|
||||
|
||||
@ -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<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;
|
||||
}
|
||||
|
||||
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配置界面,字段配置卡顿
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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<any[]>([]);
|
||||
const selectedRowIds = shallowRef<string[]>([]);
|
||||
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<any[]>([]),
|
||||
selectedRowIds: ref<string[]>([]),
|
||||
defaultVxeProps,
|
||||
selectedRows,
|
||||
selectedRowIds,
|
||||
disabledRowIds: [],
|
||||
statistics: reactive({
|
||||
has: false,
|
||||
sum: [],
|
||||
average: [],
|
||||
}),
|
||||
authsMap: ref(null),
|
||||
authsMap,
|
||||
innerEditRules: {},
|
||||
innerLinkageConfig: new Map<string, any>(),
|
||||
reloadEffectRowKeysMap: reactive({}),
|
||||
};
|
||||
// update-end--author:liaozhiyang---date:20260130---for:【QQYUN-14177】online配置界面,字段配置卡顿
|
||||
}
|
||||
|
||||
export function useRefs(): JVxeRefs {
|
||||
|
||||
@ -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<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 } 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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user