From 61127ee8db6297f45c1d564e9953dd261e881d31 Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Tue, 13 May 2025 17:20:36 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E6=95=B0=E6=8D=AE=E5=9B=9E=E6=98=BE=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ src/control/grid/grid/grid-control.util.ts | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f14cad9..83c0a2b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ - 更新分页导航栏支持流式布局,更新分页导航caption支持hover时显示title - 新增实体多数据自定义视图引擎 +### Fixed + +- 修复表格选中数据回显异常 + ## [0.7.40-alpha.15] - 2025-05-09 ### Added diff --git a/src/control/grid/grid/grid-control.util.ts b/src/control/grid/grid/grid-control.util.ts index c090f8f0..17064e61 100644 --- a/src/control/grid/grid/grid-control.util.ts +++ b/src/control/grid/grid/grid-control.util.ts @@ -301,9 +301,7 @@ export function useITableEvent(c: GridController): { function onSelectionChange(selection: ControlVO[]): void { // 选中数据在回显的时候屏蔽值变更事件,否则会递归。 - if (!forbidChange) { - c.setSelection(selection); - } + if (!forbidChange && !c.state.isLoading) c.setSelection(selection); } // 监听选中数据,操作表格来界面回显选中效果。 @@ -314,9 +312,7 @@ export function useITableEvent(c: GridController): { (): IData[] => c.state.selectedData, ], ([table, isLoaded, newVal]) => { - if (!isLoaded || !table) { - return; - } + if (!isLoaded || !table) return; if (c.state.singleSelect) { // 单选,选中效果回显。 if (newVal[0]) { @@ -327,8 +323,12 @@ export function useITableEvent(c: GridController): { } else { forbidChange = true; tableRef.value!.clearSelection(); - newVal.forEach(item => tableRef.value!.toggleRowSelection(item, true)); - forbidChange = false; + setTimeout(() => { + newVal.forEach(item => + tableRef.value!.toggleRowSelection(item, true), + ); + forbidChange = false; + }); } }, ); -- Gitee From f80d27b274c937be9def54729c07b12a71573fb6 Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Wed, 14 May 2025 11:51:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E5=BF=AB=E6=8D=B7=E9=94=AE=E5=A4=9A=E9=80=89=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 7 +- src/control/grid/grid/grid-control.util.ts | 123 +++++++++++++-------- src/control/grid/grid/grid.tsx | 2 - 3 files changed, 80 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83c0a2b8..fc621a5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,13 @@ ### Added -- 更新分页导航栏支持流式布局,更新分页导航caption支持hover时显示title +- 更新分页导航栏支持流式布局,更新分页导航caption支持hover时显示title - 新增实体多数据自定义视图引擎 +- 新增表格shift多选操作 + +### Changed + +- 优化表格ctrl多选操作 ### Fixed diff --git a/src/control/grid/grid/grid-control.util.ts b/src/control/grid/grid/grid-control.util.ts index 17064e61..edf6a66a 100644 --- a/src/control/grid/grid/grid-control.util.ts +++ b/src/control/grid/grid/grid-control.util.ts @@ -118,8 +118,6 @@ export function useITableEvent(c: GridController): { _rowIndex: number; _columnIndex: number; }) => string; - cleanKeyDown: () => void; - cleanKeyUp: () => void; cleanClick: () => void; cleanEnter: () => void; } { @@ -129,26 +127,9 @@ export function useITableEvent(c: GridController): { // 是否正在设置elementPlus表格排序回显效果 let isGridUISort = false; - // 是否按下ctrl - let isCtrlDown: boolean = false; - - let cleanKeyDown = NOOP; - let cleanKeyUp = NOOP; let cleanClick = NOOP; let cleanEnter = NOOP; - cleanKeyDown = listenJSEvent(window, 'keydown', (e: KeyboardEvent) => { - if (e.code === 'ControlLeft' && !c.state.singleSelect) { - isCtrlDown = true; - } - }); - - cleanKeyUp = listenJSEvent(window, 'keyup', (e: KeyboardEvent) => { - if (e.code === 'ControlLeft' && !c.state.singleSelect) { - isCtrlDown = false; - } - }); - if (c.state.isAutoGrid) { // 行编辑模式才监听 if (c.editShowMode === 'row') { @@ -208,10 +189,68 @@ export function useITableEvent(c: GridController): { } }); + /** + * 处理ctrl+click选中 + * + * @param {ControlVO} data + */ + function handleCtrlSelect(data: ControlVO): void { + const selection = [...c.state.selectedData]; + const index = selection.findIndex(x => x.srfkey === data.srfkey); + if (index !== -1) { + selection.splice(index, 1); + c.setSelection(selection); + } else { + c.setSelection([...selection, data]); + } + } + + // 上一次选中数据索引 + let lastSelectedIndex: number | null = null; + + /** + * 处理shift+click选中 + * + * @param {ControlVO} data + */ + function handleShiftSelect(data: ControlVO): void { + // 清除shift的默认选中样式 + window.getSelection()?.removeAllRanges(); + const index = c.findRowStateIndex(data); + const selection = [...c.state.selectedData]; + const isSelected = selection.includes(data); + if (lastSelectedIndex !== null) { + // Shift+点击,执行范围选择 + const start = Math.min(lastSelectedIndex, index); + const end = Math.max(lastSelectedIndex, index); + + if (isSelected) { + // 如果点击的是已选中项,则取消该范围内的选中 + for (let i = start; i <= end; i++) { + const itemIndex = selection.indexOf(c.state.items[i]); + if (itemIndex !== -1) { + selection.splice(itemIndex, 1); + } + } + } else { + // 否则选中该范围内的所有项 + for (let i = start; i <= end; i++) { + if (!selection.includes(c.state.items[i])) { + selection.push(c.state.items[i]); + } + } + } + c.setSelection(selection); + } else { + c.setSelection([data]); + } + lastSelectedIndex = index; + } + async function onRowClickDynamic( data: ControlVO, _column: IData, - _event: MouseEvent, + event: MouseEvent, ): Promise { // 新建行拦截行点击事件 if (data.srfuf === Srfuf.CREATE) { @@ -222,17 +261,8 @@ export function useITableEvent(c: GridController): { } return; } - if (isCtrlDown) { - const selection = [...c.state.selectedData]; - const index = selection.findIndex(x => x.srfkey === data.srfkey); - if (index !== -1) { - selection.splice(index, 1); - c.setSelection(selection); - } else { - c.setSelection([...selection, data]); - } - return; - } + if (event.ctrlKey && !c.state.singleSelect) return handleCtrlSelect(data); + if (event.shiftKey && !c.state.singleSelect) return handleShiftSelect(data); // 单行编辑模式下,行点击会触发 if (c.editShowMode === 'row' && c.allowRowEdit) { const row = c.findRowState(data); @@ -241,7 +271,7 @@ export function useITableEvent(c: GridController): { await c.switchRowEdit(row); } } else { - c.onRowClick(data as ControlVO); + await c.onRowClick(data as ControlVO); } } @@ -250,26 +280,23 @@ export function useITableEvent(c: GridController): { async function onRowClick( data: ControlVO, _column: IData, - _event: MouseEvent, + event: MouseEvent, ): Promise { + // 非shift点击时需标记选中数据 + if (!event.shiftKey) { + const index = c.findRowStateIndex(data); + const isSelected = c.state.selectedData.includes(data); + lastSelectedIndex = isSelected ? null : index; + } if (c.state.isAutoGrid) { - await onRowClickDynamic(data, _column, _event); + await onRowClickDynamic(data, _column, event); return; } // 新建行拦截行点击事件 if (data.srfuf === Srfuf.CREATE || forbidClick) return; - if (isCtrlDown) { - const selection = [...c.state.selectedData]; - const index = selection.findIndex(x => x.srfkey === data.srfkey); - if (index !== -1) { - selection.splice(index, 1); - c.setSelection(selection); - } else { - c.setSelection([...selection, data]); - } - return; - } - const target = _event.target as HTMLElement; + if (event.ctrlKey && !c.state.singleSelect) return handleCtrlSelect(data); + if (event.shiftKey && !c.state.singleSelect) return handleShiftSelect(data); + const target = event.target as HTMLElement; const { classList } = target.parentElement || {}; if (classList && classList.contains('el-table-column--selection')) { tableRef.value!.toggleRowSelection(data); @@ -283,7 +310,7 @@ export function useITableEvent(c: GridController): { await c.switchRowEdit(row, true); } } else { - c.onRowClick(data as ControlVO); + await c.onRowClick(data as ControlVO); } forbidClick = true; setTimeout(() => { @@ -464,8 +491,6 @@ export function useITableEvent(c: GridController): { onSortChange, handleRowClassName, handleHeaderCellClassName, - cleanKeyDown, - cleanKeyUp, cleanClick, cleanEnter, }; diff --git a/src/control/grid/grid/grid.tsx b/src/control/grid/grid/grid.tsx index 90ada6a4..91946b5d 100644 --- a/src/control/grid/grid/grid.tsx +++ b/src/control/grid/grid/grid.tsx @@ -396,8 +396,6 @@ export const GridControl = defineComponent({ onSortChange, handleRowClassName, handleHeaderCellClassName, - cleanKeyDown = NOOP, - cleanKeyUp = NOOP, cleanClick = NOOP, cleanEnter = NOOP, } = useITableEvent(c); -- Gitee