Prechádzať zdrojové kódy

refactor: 完善ColumnSetting的操作逻辑 (#2745)

GauharChan 2 rokov pred
rodič
commit
b97d588392

+ 2 - 0
src/components/Table/src/BasicTable.vue

@@ -184,6 +184,7 @@
         getViewColumns,
         getColumns,
         setCacheColumnsByField,
+        setCacheColumns,
         setColumns,
         getColumnsRef,
         getCacheColumns,
@@ -323,6 +324,7 @@
         getSize: () => {
           return unref(getBindValues).size as SizeType;
         },
+        setCacheColumns,
       };
       createTableContext({ ...tableAction, wrapRef, getBindValues });
 

+ 67 - 36
src/components/Table/src/components/settings/ColumnSetting.vue

@@ -99,7 +99,7 @@
   </Tooltip>
 </template>
 <script lang="ts">
-  import type { BasicColumn, ColumnChangeParam } from '../../types/table';
+  import type { BasicColumn, BasicTableProps, ColumnChangeParam } from '../../types/table';
   import {
     defineComponent,
     ref,
@@ -159,6 +159,10 @@
 
       const defaultRowSelection = omit(table.getRowSelection(), 'selectedRowKeys');
       let inited = false;
+      // 是否当前的setColums触发的
+      let isSetColumnsFromThis = false;
+      // 是否当前组件触发的setProps
+      let isSetPropsFromThis = false;
 
       const cachePlainOptions = ref<Options[]>([]);
       const plainOptions = ref<Options[] | any>([]);
@@ -172,7 +176,8 @@
         checkedList: [],
         defaultCheckList: [],
       });
-
+      /** 缓存初始化props */
+      let cacheTableProps: Partial<BasicTableProps<any>> = {};
       const checkIndex = ref(false);
       const checkSelect = ref(false);
 
@@ -185,7 +190,9 @@
       watchEffect(() => {
         const columns = table.getColumns();
         setTimeout(() => {
-          if (columns.length && !state.isInit) {
+          if (isSetColumnsFromThis) {
+            isSetColumnsFromThis = false;
+          } else if (columns.length) {
             init();
           }
         }, 0);
@@ -193,6 +200,11 @@
 
       watchEffect(() => {
         const values = unref(getValues);
+        if (isSetPropsFromThis) {
+          isSetPropsFromThis = false;
+        } else {
+          cacheTableProps = cloneDeep(values);
+        }
         checkIndex.value = !!values.showIndexColumn;
         checkSelect.value = !!values.rowSelection;
       });
@@ -209,8 +221,17 @@
         return ret;
       }
 
-      function init() {
-        const columns = getColumns();
+      async function init(isReset = false) {
+        // Sortablejs存在bug,不知道在哪个步骤中会向el append了一个childNode,因此这里先清空childNode
+        // 有可能复现上述问题的操作:拖拽一个元素,快速的上下移动,最后放到最后的位置中松手
+        plainOptions.value = [];
+        const columnListEl = unref(columnListRef);
+        if (columnListEl && (columnListEl as any).$el) {
+          const el = (columnListEl as any).$el as Element;
+          Array.from(el.children).forEach((item) => el.removeChild(item));
+        }
+        await nextTick();
+        const columns = isReset ? cloneDeep(cachePlainOptions.value) : getColumns();
 
         const checkList = table
           .getColumns({ ignoreAction: true, ignoreIndex: true })
@@ -221,31 +242,25 @@
             return item.dataIndex || item.title;
           })
           .filter(Boolean) as string[];
-
-        if (!plainOptions.value.length) {
-          plainOptions.value = columns;
-          plainSortOptions.value = columns;
-          cachePlainOptions.value = columns;
-          state.defaultCheckList = checkList;
-        } else {
-          // const fixedColumns = columns.filter((item) =>
-          //   Reflect.has(item, 'fixed')
-          // ) as BasicColumn[];
-
-          unref(plainOptions).forEach((item: BasicColumn) => {
-            const findItem = columns.find((col: BasicColumn) => col.dataIndex === item.dataIndex);
-            if (findItem) {
-              item.fixed = findItem.fixed;
-            }
-          });
-        }
-        state.isInit = true;
+        plainOptions.value = columns;
+        plainSortOptions.value = columns;
+        // 更新缓存配置
+        table.setCacheColumns?.(columns);
+        !isReset && (cachePlainOptions.value = cloneDeep(columns));
+        state.defaultCheckList = checkList;
         state.checkedList = checkList;
+        // 是否列展示全选
+        state.checkAll = checkList.length === columns.length;
+        inited = false;
+        handleVisibleChange();
       }
 
       // checkAll change
       function onCheckAllChange(e: CheckboxChangeEvent) {
-        const checkList = plainOptions.value.map((item) => item.value);
+        const checkList = plainSortOptions.value.map((item) => item.value);
+        plainSortOptions.value.forEach(
+          (item) => ((item as BasicColumn).defaultHidden = !e.target.checked),
+        );
         if (e.target.checked) {
           state.checkedList = checkList;
           setColumns(checkList);
@@ -270,6 +285,9 @@
         checkedList.sort((prev, next) => {
           return sortList.indexOf(prev) - sortList.indexOf(next);
         });
+        unref(plainSortOptions).forEach((item) => {
+          (item as BasicColumn).defaultHidden = !checkedList.includes(item.value);
+        });
         setColumns(checkedList);
       }
 
@@ -277,11 +295,14 @@
       let sortableOrder: string[] = [];
       // reset columns
       function reset() {
-        state.checkedList = [...state.defaultCheckList];
-        state.checkAll = true;
-        plainOptions.value = unref(cachePlainOptions);
-        plainSortOptions.value = unref(cachePlainOptions);
-        setColumns(table.getCacheColumns());
+        setColumns(cachePlainOptions.value);
+        init(true);
+        checkIndex.value = !!cacheTableProps.showIndexColumn;
+        checkSelect.value = !!cacheTableProps.rowSelection;
+        table.setProps({
+          showIndexColumn: checkIndex.value,
+          rowSelection: checkSelect.value ? defaultRowSelection : undefined,
+        });
         sortable.sort(sortableOrder);
       }
 
@@ -316,12 +337,7 @@
               }
 
               plainSortOptions.value = columns;
-
-              setColumns(
-                columns
-                  .map((col: Options) => col.value)
-                  .filter((value: string) => state.checkedList.includes(value)),
-              );
+              setColumns(columns.filter((item) => state.checkedList.includes(item.value)));
             },
           });
           // 记录原始order 序列
@@ -332,6 +348,8 @@
 
       // Control whether the serial number column is displayed
       function handleIndexCheckChange(e: CheckboxChangeEvent) {
+        isSetPropsFromThis = true;
+        isSetColumnsFromThis = true;
         table.setProps({
           showIndexColumn: e.target.checked,
         });
@@ -339,6 +357,8 @@
 
       // Control whether the check box is displayed
       function handleSelectCheckChange(e: CheckboxChangeEvent) {
+        isSetPropsFromThis = true;
+        isSetColumnsFromThis = true;
         table.setProps({
           rowSelection: e.target.checked ? defaultRowSelection : undefined,
         });
@@ -360,11 +380,14 @@
         if (isFixed && !item.width) {
           item.width = 100;
         }
+        updateSortOption(item);
         table.setCacheColumnsByField?.(item.dataIndex as string, { fixed: isFixed });
         setColumns(columns);
       }
 
       function setColumns(columns: BasicColumn[] | string[]) {
+        isSetPropsFromThis = true;
+        isSetColumnsFromThis = true;
         table.setColumns(columns);
         const data: ColumnChangeParam[] = unref(plainSortOptions).map((col) => {
           const visible =
@@ -384,6 +407,14 @@
           : getParentContainer();
       }
 
+      function updateSortOption(column: BasicColumn) {
+        plainSortOptions.value.forEach((item) => {
+          if (item.value === column.dataIndex) {
+            Object.assign(item, column);
+          }
+        });
+      }
+
       return {
         t,
         ...toRefs(state),

+ 5 - 0
src/components/Table/src/hooks/useColumns.ts

@@ -260,6 +260,10 @@ export function useColumns(
   function getCacheColumns() {
     return cacheColumns;
   }
+  function setCacheColumns(columns: BasicColumn[]) {
+    if (!isArray(columns)) return;
+    cacheColumns = columns.filter((item) => !item.flag);
+  }
 
   return {
     getColumnsRef,
@@ -268,6 +272,7 @@ export function useColumns(
     setColumns,
     getViewColumns,
     setCacheColumnsByField,
+    setCacheColumns,
   };
 }
 

+ 1 - 0
src/components/Table/src/types/table.ts

@@ -116,6 +116,7 @@ export interface TableActionType {
   setShowPagination: (show: boolean) => Promise<void>;
   getShowPagination: () => boolean;
   setCacheColumnsByField?: (dataIndex: string | undefined, value: BasicColumn) => void;
+  setCacheColumns?: (columns: BasicColumn[]) => void;
 }
 
 export interface FetchSetting {