提交 a1ffb618 编写于 作者: V vben

perf(table): optimize effect performance

上级 84b8302c
<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,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);
}
......
......@@ -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,
......
......@@ -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;
}
......
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;
......
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);
......
import { Ref, ref, watch, unref } from 'vue';
import { BasicTableProps } from '../types/table';
import type { BasicTableProps } from '../types/table';
/**
* @description:
......
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');
......
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;
}
......
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';
......
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(() => {
......
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[];
}
/**
* 添加节点
*/
......
......@@ -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(() => {
......
.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;
}
......
......@@ -79,6 +79,7 @@
align-items: center;
padding-left: 16px;
cursor: pointer;
justify-content: center;
.logo-title {
display: none;
......
......@@ -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);
}
}
......
......@@ -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>
);
}
......
......@@ -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'] {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册