瀏覽代碼

perf(table): optimize effect performance

vben 4 年之前
父節點
當前提交
a1ffb61804

+ 4 - 4
src/components/Container/src/collapse/CollapseContainer.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="collapse-container p-2">
     <CollapseHeader v-bind="$props" :show="show" @expand="handleExpand">
-			<template #title>
-				<slot name="title" />
-			</template>
+      <template #title>
+        <slot name="title" />
+      </template>
     </CollapseHeader>
     <CollapseTransition :enable="canExpan">
       <Skeleton v-if="loading" />
@@ -102,7 +102,7 @@
 <style lang="less">
   .collapse-container {
     background: #fff;
-    border-radius: 8px;
+    border-radius: 2px;
     transition: all 0.3s ease-in-out;
 
     &.no-shadow {

+ 2 - 1
src/components/Menu/src/index.less

@@ -2,12 +2,13 @@
 
 .active-style() {
   color: @white;
+  // background: @primary-color !important;
   background: linear-gradient(
     118deg,
     rgba(@primary-color, 0.8),
     rgba(@primary-color, 1)
   ) !important;
-  border-radius: 2px;
+  // border-radius: 2px;
   box-shadow: 0 0 4px 1px rgba(@primary-color, 0.7);
 }
 

+ 12 - 12
src/components/Table/src/BasicTable.vue

@@ -21,8 +21,8 @@
     </BasicForm>
     <Table
       ref="tableElRef"
-      :rowClassName="getRowClassName"
       v-bind="getBindValues"
+      :rowClassName="getRowClassName"
       v-show="getEmptyDataIsShowTable"
       @change="handleTableChange"
     >
@@ -33,9 +33,6 @@
   </div>
 </template>
 <script lang="ts">
-  import { defineComponent, ref, computed, unref, watch, nextTick, toRaw } from 'vue';
-  import { Table } from 'ant-design-vue';
-  import { basicProps } from './props';
   import type {
     BasicTableProps,
     FetchParams,
@@ -45,12 +42,18 @@
     SorterResult,
     TableCustomRecord,
   } from './types/table';
+  import { PaginationProps } from './types/pagination';
 
-  import { isFunction, isString } from '/@/utils/is';
-
+  import { defineComponent, ref, computed, unref, watch, nextTick, toRaw } from 'vue';
+  import { Table } from 'ant-design-vue';
   import renderTitle from './components/renderTitle';
   import renderFooter from './components/renderFooter';
   import renderExpandIcon from './components/renderExpandIcon';
+  import { BasicForm, FormProps, useForm } from '/@/components/Form/index';
+
+  import { isFunction, isString } from '/@/utils/is';
+  import { deepMerge } from '/@/utils';
+  import { omit } from 'lodash-es';
 
   import { usePagination } from './hooks/usePagination';
   import { useColumns } from './hooks/useColumns';
@@ -59,13 +62,10 @@
   import { useRowSelection } from './hooks/useRowSelection';
   import { useTableScroll } from './hooks/useTableScroll';
   import { provideTable } from './hooks/useProvinceTable';
-  import { BasicForm, FormProps, useForm } from '/@/components/Form/index';
-  import { omit } from 'lodash-es';
-  import { ROW_KEY } from './const';
-  import { PaginationProps } from './types/pagination';
-  import { deepMerge } from '/@/utils';
-  import { useEvent } from '/@/hooks/event/useEvent';
 
+  import { useEvent } from '/@/hooks/event/useEvent';
+  import { basicProps } from './props';
+  import { ROW_KEY } from './const';
   import './style/index.less';
   export default defineComponent({
     props: basicProps,

+ 1 - 1
src/components/Table/src/hooks/useColumns.ts

@@ -101,7 +101,7 @@ export function useColumns(
       columnsRef.value = columns as any;
     } else {
       const newColumns = unref(cacheColumnsRef).filter((item) =>
-        (columns as string[]).includes(item.key! || item.dataIndex!)
+        (columns as string[]).includes(`${item.key}`! || item.dataIndex!)
       );
       columnsRef.value = newColumns;
     }

+ 8 - 4
src/components/Table/src/hooks/useDataSource.ts

@@ -1,13 +1,17 @@
-import { useTimeout } from '/@/hooks/core/useTimeout';
-import { BasicTableProps, FetchParams } from '../types/table';
-import { PaginationProps } from '../types/pagination';
+import type { BasicTableProps, FetchParams } from '../types/table';
+import type { PaginationProps } from '../types/pagination';
+
 import { watch, ref, unref, ComputedRef, computed, onMounted, Ref } from 'vue';
+
+import { useTimeout } from '/@/hooks/core/useTimeout';
+
 import { buildUUID } from '/@/utils/uuid';
 import { isFunction, isBoolean } from '/@/utils/is';
-import { FETCH_SETTING, ROW_KEY } from '../const';
 import { get } from 'lodash-es';
+
 import { useProps } from './useProps';
 
+import { FETCH_SETTING, ROW_KEY } from '../const';
 interface ActionType {
   getPaginationRef: ComputedRef<false | PaginationProps>;
   setPagination: (info: Partial<PaginationProps>) => void;

+ 5 - 3
src/components/Table/src/hooks/usePagination.tsx

@@ -1,11 +1,13 @@
+import type { PaginationProps } from '../types/pagination';
+import type { BasicTableProps } from '../types/table';
+
 import { computed, unref, ref, ComputedRef } from 'vue';
-import { PaginationProps } from '../types/pagination';
-import { isBoolean } from '/@/utils/is';
 import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
 
+import { isBoolean } from '/@/utils/is';
+
 import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '../const';
 import { useProps } from './useProps';
-import { BasicTableProps } from '../..';
 export function usePagination(refProps: ComputedRef<BasicTableProps>) {
   const configRef = ref<PaginationProps>({});
   const { propsRef } = useProps(refProps);

+ 2 - 1
src/components/Table/src/hooks/useProps.ts

@@ -1,5 +1,6 @@
 import { Ref, ref, watch, unref } from 'vue';
-import { BasicTableProps } from '../types/table';
+
+import type { BasicTableProps } from '../types/table';
 
 /**
  * @description:

+ 2 - 1
src/components/Table/src/hooks/useProvinceTable.ts

@@ -1,6 +1,7 @@
 import type { Ref } from 'vue';
+import type { TableActionType } from '../types/table';
+
 import { provide, inject } from 'vue';
-import { TableActionType } from '../types/table';
 
 const key = Symbol('table');
 

+ 3 - 1
src/components/Table/src/hooks/useRowSelection.ts

@@ -1,5 +1,6 @@
-import { computed, ref, unref, ComputedRef } from 'vue';
 import type { BasicTableProps, TableRowSelection } from '../types/table';
+
+import { computed, ref, unref, ComputedRef } from 'vue';
 import { useProps } from './useProps';
 
 /* eslint-disable */
@@ -28,6 +29,7 @@ export function useRowSelection(refProps: ComputedRef<BasicTableProps>, emit: Em
       ...rowSelection,
     };
   });
+
   function setSelectedRowKeys(rowKeys: string[]) {
     selectedRowKeysRef.value = rowKeys;
   }

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

@@ -1,5 +1,6 @@
 import type { BasicTableProps, TableActionType, FetchParams, BasicColumn } from '../types/table';
 import type { PaginationProps } from '../types/pagination';
+
 import { ref, getCurrentInstance, onUnmounted, unref } from 'vue';
 import { isProdMode } from '/@/utils/env';
 

+ 46 - 41
src/components/Table/src/hooks/useTableScroll.ts

@@ -1,12 +1,13 @@
-import { BasicTableProps } from '../types/table';
+import type { BasicTableProps } from '../types/table';
 import { computed, Ref, onMounted, unref, ref, nextTick, ComputedRef, watch } from 'vue';
+
+import { injectModal } from '/@/components/Modal/src/provideModal';
+
 import { getViewportOffset } from '/@/utils/domUtils';
-import { triggerWindowResize } from '/@/utils/event/triggerWindowResizeEvent';
 import { isBoolean } from '/@/utils/is';
-import { useTimeout } from '/@/hooks/core/useTimeout';
+
 import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
 import { useProps } from './useProps';
-import { injectModal } from '/@/components/Modal/src/provideModal';
 
 export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRef: Ref<any>) {
   const { propsRef } = useProps(refProps);
@@ -29,7 +30,9 @@ export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRe
     calcTableHeight();
   }
 
-  async function calcTableHeight(cb?: () => void) {
+  let paginationEl: HTMLElement | null;
+  let footerEl: HTMLElement | null;
+  async function calcTableHeight() {
     const { canResize, resizeHeightOffset, pagination, maxHeight } = unref(propsRef);
     if (!canResize) return;
 
@@ -39,40 +42,44 @@ export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRe
 
     const tableEl: Element = table.$el;
     if (!tableEl) return;
-
-    const el: HTMLElement | null = tableEl.querySelector('.ant-table-thead ');
+    const headEl = tableEl.querySelector('.ant-table-thead ');
     // const layoutMain: Element | null = document.querySelector('.default-layout__main ');
-    if (!el) return;
+    if (!headEl) return;
 
     // 表格距离底部高度
-    const { bottomIncludeBody } = getViewportOffset(el);
+    const { bottomIncludeBody } = getViewportOffset(headEl);
     // 表格高度+距离底部高度-自定义偏移量
 
     const paddingHeight = 32;
     const borderHeight = 2 * 2;
     // 分页器高度
 
-    // TODO 先固定20
-    const paginationHeight = 20;
-    // if (!isBoolean(pagination)) {
-    //   const paginationDom = tableEl.querySelector('.ant-pagination') as HTMLElement;
-    //   if (paginationDom) {
-    //     const offsetHeight = paginationDom.offsetHeight;
-    //     paginationHeight += offsetHeight || 0;
-    //   }
-    // }
+    let paginationHeight = 2;
+    if (!isBoolean(pagination)) {
+      if (!paginationEl) {
+        paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement;
+      }
+      if (paginationEl) {
+        const offsetHeight = paginationEl.offsetHeight;
+        paginationHeight += offsetHeight || 0;
+      } else {
+        // TODO 先固定24
+        paginationHeight += 24;
+      }
+    }
 
     let footerHeight = 0;
     if (!isBoolean(pagination)) {
-      const footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement;
-      if (footerEl) {
+      if (!footerEl) {
+        footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement;
+      } else {
         const offsetHeight = footerEl.offsetHeight;
         footerHeight += offsetHeight || 0;
       }
     }
     let headerHeight = 0;
-    if (el) {
-      headerHeight = (el as HTMLElement).offsetHeight;
+    if (headEl) {
+      headerHeight = (headEl as HTMLElement).offsetHeight;
     }
     tableHeightRef.value =
       bottomIncludeBody -
@@ -82,13 +89,13 @@ export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRe
       paginationHeight -
       footerHeight -
       headerHeight;
-    useTimeout(() => {
+
+    setTimeout(() => {
       tableHeightRef.value =
         tableHeightRef.value! > maxHeight! ? (maxHeight as number) : tableHeightRef.value;
-      cb && cb();
       //  解决表格放modal内的时候,modal自适应高度计算问题
       redoModalHeight && redoModalHeight();
-    }, 0);
+    }, 16);
   }
 
   const getCanResize = computed(() => {
@@ -98,24 +105,22 @@ export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRe
 
   useWindowSizeFn(calcTableHeight, 100);
 
-  // function clear() {
-  //   window.clearInterval(timer);
-  // }
-
   onMounted(() => {
     if (unref(getCanResize)) {
-      calcTableHeight();
-      const hasFixedLeft = (unref(propsRef).columns || []).some((item) => item.fixed === 'left');
-      // TODO antv table问题情况太多,只能先用下面方式定时器hack
-      useTimeout(() => {
-        calcTableHeight(() => {
-          // 有左侧固定列的时候才有问题
-          hasFixedLeft &&
-            useTimeout(() => {
-              triggerWindowResize();
-            }, 300);
-        });
-      }, 200);
+      nextTick(() => {
+        calcTableHeight();
+      });
+      // const hasFixedLeft = (unref(propsRef).columns || []).some((item) => item.fixed === 'left');
+      // // TODO antv table问题情况太多,只能先用下面方式定时器hack
+      // useTimeout(() => {
+      //   calcTableHeight(() => {
+      //     // 有左侧固定列的时候才有问题
+      //     hasFixedLeft &&
+      //       useTimeout(() => {
+      //         triggerWindowResize();
+      //       }, 300);
+      //   });
+      // }, 200);
     }
   });
   const getScrollRef = computed(() => {

+ 12 - 9
src/components/Tree/src/BasicTree.tsx

@@ -1,18 +1,20 @@
+import type { ReplaceFields, TreeItem, Keys, CheckKeys, InsertNodeParams } from './types';
+
 import { defineComponent, reactive, computed, unref, ref, watchEffect } from 'vue';
 import { Tree } from 'ant-design-vue';
-import { extendSlots } from '/@/utils/helper/tsxHelper';
-import { useContextMenu, ContextMenuItem } from '/@/hooks/web/useContextMenu';
-import { basicProps } from './props';
-import { isFunction } from '/@/utils/is';
-import { omit } from 'lodash-es';
 import { DownOutlined } from '@ant-design/icons-vue';
 
-import type { ReplaceFields, TreeItem, Keys, CheckKeys, InsertNodeParams } from './types';
+import { useContextMenu, ContextMenuItem } from '/@/hooks/web/useContextMenu';
+
+import { isFunction } from '/@/utils/is';
+import { omit, cloneDeep } from 'lodash-es';
+import { forEach } from '/@/utils/helper/treeHelper';
+import { extendSlots } from '/@/utils/helper/tsxHelper';
 import { tryTsxEmit } from '/@/utils/helper/vueHelper';
 
+import { basicProps } from './props';
+
 import './index.less';
-import { forEach } from '/@/utils/helper/treeHelper';
-import { cloneDeep } from 'lodash-es';
 
 interface State {
   expandedKeys: Keys;
@@ -72,7 +74,6 @@ export default defineComponent({
       if (!data) {
         return null;
       }
-
       return data.map((item) => {
         const { title: titleField, key: keyField, children: childrenField } = unref(
           getReplaceFields
@@ -94,6 +95,7 @@ export default defineComponent({
         );
       });
     }
+
     // 处理右键事件
     async function handleRightClick({ event, node }: any) {
       const { rightMenuList: menuList = [], beforeRightClick } = props;
@@ -154,6 +156,7 @@ export default defineComponent({
       }
       return res as string[] | number[];
     }
+
     /**
      * 添加节点
      */

+ 4 - 0
src/components/VirtualScroll/src/index.tsx

@@ -75,6 +75,7 @@ export default defineComponent({
     function getFirst(): number {
       return Math.floor(state.scrollTop / unref(getItemHeightRef));
     }
+
     function onScroll() {
       const wrapEl = unref(wrapElRef);
       if (!wrapEl) {
@@ -84,10 +85,12 @@ export default defineComponent({
       state.first = getFirst();
       state.last = getLast(state.first);
     }
+
     function renderChildren() {
       const { items = [] } = props;
       return items.slice(unref(getFirstToRenderRef), unref(getLastToRenderRef)).map(genChild);
     }
+
     function genChild(item: any, index: number) {
       index += unref(getFirstToRenderRef);
 
@@ -98,6 +101,7 @@ export default defineComponent({
         </div>
       );
     }
+
     onMounted(() => {
       state.last = getLast(0);
       nextTick(() => {

+ 23 - 53
src/design/ant/pagination.less

@@ -1,15 +1,9 @@
 .ant-pagination {
   &.mini {
-    height: 20px;
-    font-size: 13px;
-
     .ant-pagination-prev,
     .ant-pagination-next {
-      width: 20px;
-      height: 20px;
-      min-width: 20px;
-      line-height: 20px;
-      color: @border-color-shallow-dark;
+      font-size: 12px;
+      color: @text-color-base;
       border: 1px solid;
     }
 
@@ -17,15 +11,23 @@
     .ant-pagination-next:hover,
     .ant-pagination-item:focus,
     .ant-pagination-item:hover {
-      color: @primary-color;
-      border: 1px solid @primary-color;
+      a {
+        color: @primary-color;
+      }
     }
 
+    .ant-pagination-prev,
+    .ant-pagination-next,
     .ant-pagination-item {
-      height: 20px;
-      min-width: 20px;
-      margin: 0 3px;
-      line-height: 20px;
+      margin: 0 4px;
+      background: #f4f4f5 !important;
+      border: none;
+      border-radius: none !important;
+
+      a {
+        margin-top: 1px;
+        color: #606266;
+      }
 
       &:last-child {
         margin-right: 0 !important;
@@ -33,58 +35,26 @@
     }
 
     .ant-pagination-item-active {
-      background: @primary-color;
+      background: @primary-color !important;
+      border: none;
+      border-radius: none !important;
 
       a {
-        color: @white;
+        color: @white !important;
       }
     }
 
     .ant-pagination-options {
-      margin-left: 20px;
-    }
-
-    .ant-select-sm .ant-select-selection--single {
-      height: 20px;
-    }
-
-    .ant-pagination-options,
-    .ant-pagination-total-text,
-    .ant-pagination-options-quick-jumper {
-      height: 20px;
-      line-height: 20px;
-    }
-
-    .ant-select-selection__rendered {
-      height: 18px;
-      line-height: 18px;
-    }
-
-    .ant-pagination-total-text,
-    .ant-select-selection__rendered,
-    .ant-select-dropdown-menu-item,
-    .ant-pagination-options-quick-jumper {
-      font-size: 13px;
+      margin-left: 12px;
     }
 
     .ant-pagination-options-quick-jumper input {
-      width: 40px;
-      height: 20px;
+      height: 22px;
       margin: 0 6px;
-      line-height: 20px;
+      line-height: 22px;
       text-align: center;
     }
 
-    .ant-pagination-jump-prev,
-    .ant-pagination-jump-next {
-      height: 20px;
-      line-height: 20px;
-    }
-
-    .ant-pagination-options-size-changer.ant-select {
-      margin-right: 20px;
-    }
-
     .ant-select-arrow {
       color: @border-color-shallow-dark;
     }

+ 1 - 0
src/layouts/Logo.vue

@@ -79,6 +79,7 @@
     align-items: center;
     padding-left: 16px;
     cursor: pointer;
+    justify-content: center;
 
     .logo-title {
       display: none;

+ 1 - 1
src/layouts/default/index.less

@@ -103,7 +103,7 @@
     padding: 0;
     line-height: @multiple-height;
     background: @border-color-shallow-light;
-    box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.12);
+    box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
   }
 }
 

+ 2 - 2
src/layouts/default/multitabs/TabContent.tsx

@@ -5,7 +5,7 @@ import { getScaleAction, TabContentProps } from './tab.data';
 import { defineComponent, unref, computed } from 'vue';
 import { Dropdown } from '/@/components/Dropdown/index';
 import Icon from '/@/components/Icon/index';
-import { DoubleRightOutlined } from '@ant-design/icons-vue';
+import { RightOutlined } from '@ant-design/icons-vue';
 import { appStore } from '/@/store/modules/app';
 
 import { TabContentEnum } from './tab.data';
@@ -74,7 +74,7 @@ export default defineComponent({
     function renderExtraContent() {
       return (
         <span class={`multiple-tabs-content__extra `}>
-          <DoubleRightOutlined />
+          <RightOutlined />
         </span>
       );
     }

+ 3 - 8
src/layouts/default/multitabs/index.less

@@ -20,6 +20,7 @@
 
       .ant-tabs-tab {
         height: calc(@multiple-height - 2px);
+        padding-right: 12px;
         line-height: calc(@multiple-height - 2px);
         color: @text-color-call-out;
         background: @white;
@@ -37,17 +38,10 @@
           &:hover {
             svg {
               width: 0.8em;
-              transition: all 0.1s;
             }
           }
         }
 
-        &:hover {
-          .ant-tabs-close-x {
-            display: block;
-          }
-        }
-
         > div {
           display: flex;
           justify-content: center;
@@ -106,9 +100,10 @@
     width: @multiple-height;
     height: @multiple-height;
     line-height: @multiple-height;
-    color: @primary-color;
+    color: #999;
     text-align: center;
     cursor: pointer;
+    border-left: 1px solid #eee;
     // box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
 
     span[role='img'] {