Ver código fonte

fix(BasicTable): selection wrong by click input when cross pages (#3540). resolve #3539

xachary 1 ano atrás
pai
commit
69c36021fa

+ 53 - 5
src/components/Table/src/hooks/useRowSelection.ts

@@ -22,10 +22,58 @@ export function useRowSelection(
 
     return {
       selectedRowKeys: unref(selectedRowKeysRef),
-      onChange: (selectedRowKeys: Key[], selectedRows: any[]) => {
-        setSelectedRowKeys(selectedRowKeys);
-        // 维持外部定义的onChange回调
-        rowSelection.onChange?.(selectedRowKeys, selectedRows);
+      onChange: (selectedRowKeys: Key[], selectedRows: any[], isClickCustomRow?: boolean) => {
+        if (isClickCustomRow) {
+          // 点击行触发
+
+          // 维持外部定义的 onChange 回调
+          rowSelection.onChange?.(selectedRowKeys, selectedRows);
+        } else {
+          // 点击 checkbox/radiobox 触发
+
+          // 取出【当前页】所有 keys
+          const rowKey = propsRef.value.rowKey;
+          const currentPageKeys = tableData.value.map(
+            (o) => o[(isFunction(rowKey) ? rowKey(o) : rowKey) || 'key'],
+          );
+
+          // 从【所有分页】已选的keys,且属于【当前页】的部分
+          for (const selectedKey of selectedRowKeysRef.value.filter((k) =>
+            currentPageKeys.includes(k),
+          )) {
+            // 判断是否已经不存在于【当前页】
+            if (selectedRowKeys.findIndex((k) => k === selectedKey) < 0) {
+              // 不存在 = 取消勾选
+              const removeIndex = selectedRowKeysRef.value.findIndex((k) => k === selectedKey);
+              if (removeIndex > -1) {
+                // 取消勾选
+                selectedRowKeysRef.value.splice(removeIndex, 1);
+                selectedRowRef.value.splice(removeIndex, 1);
+              }
+            }
+          }
+
+          // 存在于【当前页】,但不存在于【所有分页】,则认为是新增的
+          for (const selectedKey of selectedRowKeys) {
+            const existIndex = selectedRowKeysRef.value.findIndex((k) => k === selectedKey);
+            if (existIndex < 0) {
+              // 新增勾选
+              selectedRowKeysRef.value.push(selectedKey);
+              const record = selectedRows.find(
+                (o) => o[(isFunction(rowKey) ? rowKey(o) : rowKey) || 'key'] === selectedKey,
+              );
+              if (record) {
+                selectedRowRef.value.push(record);
+              }
+            }
+          }
+
+          // 赋值调整过的值
+          setSelectedRowKeys(selectedRowKeysRef.value);
+
+          // 维持外部定义的onChange回调
+          rowSelection.onChange?.(selectedRowKeysRef.value, selectedRowRef.value);
+        }
       },
       ...omit(rowSelection, ['onChange']),
     };
@@ -45,7 +93,7 @@ export function useRowSelection(
         const { rowSelection } = unref(propsRef);
         if (rowSelection) {
           const { onChange } = rowSelection;
-          if (onChange && isFunction(onChange)) onChange(getSelectRowKeys(), getSelectRows());
+          if (onChange && isFunction(onChange)) onChange(getSelectRowKeys(), getSelectRows(), true);
         }
         emit('selection-change', {
           keys: getSelectRowKeys(),

+ 5 - 2
src/components/Table/src/types/table.ts

@@ -22,9 +22,12 @@ export interface TableCurrentDataSource<T = Recordable> {
 export interface TableRowSelection<T = any> extends ITableRowSelection {
   /**
    * Callback executed when selected rows change
-   * @type Function
+   * @param selectedRowKeys 已选的keys
+   * @param selectedRows 已选的records
+   * @param isClickCustomRow 是否是点击行触发(反之,就是点击checkbox/radiobox)
+   * @returns void
    */
-  onChange?: (selectedRowKeys: Key[], selectedRows: T[]) => any;
+  onChange?: (selectedRowKeys: Key[], selectedRows: T[], isClickCustomRow?: boolean) => void;
 
   /**
    * Callback executed when select/deselect one row