瀏覽代碼

feat(table component): add 'scrollTo' table action (#1538)

George Tan 3 年之前
父節點
當前提交
598ce5a1bf

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

@@ -52,6 +52,7 @@
   import { useLoading } from './hooks/useLoading';
   import { useRowSelection } from './hooks/useRowSelection';
   import { useTableScroll } from './hooks/useTableScroll';
+  import { useTableScrollTo } from './hooks/useTableScrollTo';
   import { useCustomRow } from './hooks/useCustomRow';
   import { useTableStyle } from './hooks/useTableStyle';
   import { useTableHeader } from './hooks/useTableHeader';
@@ -186,6 +187,8 @@
         getDataSourceRef,
       );
 
+      const { scrollTo } = useTableScrollTo(tableElRef, getDataSourceRef);
+
       const { customRow } = useCustomRow(getProps, {
         setSelectedRowKeys,
         getSelectRowKeys,
@@ -298,6 +301,7 @@
         setCacheColumnsByField,
         expandAll,
         collapseAll,
+        scrollTo,
         getSize: () => {
           return unref(getBindValues).size as SizeType;
         },

+ 55 - 0
src/components/Table/src/hooks/useScrollTo.ts

@@ -0,0 +1,55 @@
+import type { ComputedRef, Ref } from 'vue';
+import { nextTick, unref } from 'vue';
+import { warn } from '/@/utils/log';
+
+export function useTableScrollTo(
+  tableElRef: Ref<ComponentRef>,
+  getDataSourceRef: ComputedRef<Recordable[]>,
+) {
+  let bodyEl: HTMLElement | null;
+
+  async function findTargetRowToScroll(targetRowData: Recordable) {
+    const { id } = targetRowData;
+    const targetRowEl: HTMLElement | null | undefined = bodyEl?.querySelector(
+      `[data-row-key="${id}"]`,
+    );
+    //Add a delay to get new dataSource
+    await nextTick();
+    bodyEl?.scrollTo({
+      top: targetRowEl?.offsetTop ?? 0,
+      behavior: 'smooth',
+    });
+  }
+
+  function scrollTo(pos: string): void {
+    const table = unref(tableElRef);
+    if (!table) return;
+
+    const tableEl: Element = table.$el;
+    if (!tableEl) return;
+
+    if (!bodyEl) {
+      bodyEl = tableEl.querySelector('.ant-table-body');
+      if (!bodyEl) return;
+    }
+
+    const dataSource = unref(getDataSourceRef);
+    if (!dataSource) return;
+
+    // judge pos type
+    if (pos === 'top') {
+      findTargetRowToScroll(dataSource[0]);
+    } else if (pos === 'bottom') {
+      findTargetRowToScroll(dataSource[dataSource.length - 1]);
+    } else {
+      const targetRowData = dataSource.find((data) => data.id === pos);
+      if (targetRowData) {
+        findTargetRowToScroll(targetRowData);
+      } else {
+        warn(`id: ${pos} doesn't exist`);
+      }
+    }
+  }
+
+  return { scrollTo };
+}

+ 3 - 0
src/components/Table/src/hooks/useTable.ts

@@ -155,6 +155,9 @@ export function useTable(tableProps?: Props): [
     collapseAll: () => {
       getTableInstance().collapseAll();
     },
+    scrollTo: (pos: string) => {
+      getTableInstance().scrollTo(pos);
+    },
   };
 
   return [register, methods];

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

@@ -88,6 +88,7 @@ export interface TableActionType {
   clearSelectedRowKeys: () => void;
   expandAll: () => void;
   collapseAll: () => void;
+  scrollTo: (pos: string) => void; // pos: id | "top" | "bottom"
   getSelectRowKeys: () => string[];
   deleteSelectRowByKey: (key: string) => void;
   setPagination: (info: Partial<PaginationProps>) => void;