Unverified 提交 dd158a17 作者: lzdjack 提交者: GitHub

feat: 添加table继承父元素高度的功能 (#1523)

在保证了原有的高度计算上,额外新增继承父级高度, 只需设置isCanResizeParent:true
上级 c8d59a0b
<template>
<div ref="wrapRef" :class="getWrapperClass">
<BasicForm
ref="formRef"
submitOnReset
v-bind="getFormProps"
v-if="getBindValues.useSearchForm"
......@@ -25,7 +26,7 @@
<slot :name="item" v-bind="data || {}"></slot>
</template>
<template #[`header-${column.dataIndex}`] v-for="column in columns" :key="column.dataIndex">
<template #[`header-${column.dataIndex}`] v-for="(column, index) in columns" :key="index">
<HeaderCell :column="column" />
</template>
</Table>
......@@ -97,6 +98,7 @@
const tableData = ref<Recordable[]>([]);
const wrapRef = ref(null);
const formRef = ref(null);
const innerPropsRef = ref<Partial<BasicTableProps>>();
const { prefixCls } = useDesign('basic-table');
......@@ -185,6 +187,8 @@
getColumnsRef,
getRowSelectionRef,
getDataSourceRef,
wrapRef,
formRef,
);
const { scrollTo } = useTableScrollTo(tableElRef, getDataSourceRef);
......@@ -318,6 +322,7 @@
emit('register', tableAction, formActions);
return {
formRef,
tableElRef,
getBindValues,
getLoading,
......@@ -352,6 +357,7 @@
.@{prefix-cls} {
max-width: 100%;
height: 100%;
&-row__striped {
td {
......
import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/table';
import type { Ref, ComputedRef } from 'vue';
import { Ref, ComputedRef, ref } from 'vue';
import { computed, unref, nextTick, watch } from 'vue';
import { getViewportOffset } from '/@/utils/domUtils';
import { isBoolean } from '/@/utils/is';
......@@ -14,7 +14,10 @@ export function useTableScroll(
columnsRef: ComputedRef<BasicColumn[]>,
rowSelectionRef: ComputedRef<TableRowSelection | null>,
getDataSourceRef: ComputedRef<Recordable[]>,
wrapRef: Ref<HTMLElement | null>,
formRef: Ref<ComponentRef>,
) {
const tableHeightRef: Ref<Nullable<number | string>> = ref(167);
const modalFn = useModalContext();
// Greater than animation time 280
......@@ -41,7 +44,8 @@ export function useTableScroll(
});
}
function setHeight() {
function setHeight(height: number) {
tableHeightRef.value = height;
// Solve the problem of modal adaptive height calculation when the form is placed in the modal
modalFn?.redoModalHeight?.();
}
......@@ -52,7 +56,8 @@ export function useTableScroll(
let bodyEl: HTMLElement | null;
async function calcTableHeight() {
const { resizeHeightOffset, pagination, maxHeight } = unref(propsRef);
const { resizeHeightOffset, pagination, maxHeight, isCanResizeParent, useSearchForm } =
unref(propsRef);
const tableData = unref(getDataSourceRef);
const table = unref(tableElRef);
......@@ -94,11 +99,8 @@ export function useTableScroll(
if (!headEl) return;
// Table height from bottom
const { bottomIncludeBody } = getViewportOffset(headEl);
// Table height from bottom height-custom offset
const paddingHeight = 32;
let paddingHeight = 32;
// Pager height
let paginationHeight = 2;
if (!isBoolean(pagination)) {
......@@ -129,6 +131,35 @@ export function useTableScroll(
headerHeight = (headEl as HTMLElement).offsetHeight;
}
let bottomIncludeBody = 0;
if (unref(wrapRef) && isCanResizeParent) {
const tablePadding = 12;
const formMargin = 16;
let paginationMargin = 10;
const wrapHeight = unref(wrapRef)?.offsetHeight ?? 0;
let formHeight = unref(formRef)?.$el.offsetHeight ?? 0;
if (formHeight) {
formHeight += formMargin;
}
if (isBoolean(pagination) && !pagination) {
paginationMargin = 0;
}
if (isBoolean(useSearchForm) && !useSearchForm) {
paddingHeight = 0;
}
const headerCellHeight =
(tableEl.querySelector('.ant-table-title') as HTMLElement)?.offsetHeight ?? 0;
console.log(wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin);
bottomIncludeBody =
wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin;
} else {
// Table height from bottom
bottomIncludeBody = getViewportOffset(headEl).bottomIncludeBody;
}
let height =
bottomIncludeBody -
(resizeHeightOffset || 0) -
......@@ -136,9 +167,8 @@ export function useTableScroll(
paginationHeight -
footerHeight -
headerHeight;
height = (height > maxHeight! ? (maxHeight as number) : height) ?? height;
setHeight();
setHeight(height);
bodyEl!.style.height = `${height}px`;
}
......@@ -176,10 +206,11 @@ export function useTableScroll(
});
const getScrollRef = computed(() => {
const tableHeight = unref(tableHeightRef);
const { canResize, scroll } = unref(propsRef);
return {
x: unref(getScrollX),
y: canResize ? '100%' : null,
y: canResize ? tableHeight : null,
scrollToFirstRowOnChange: false,
...scroll,
};
......
......@@ -97,6 +97,7 @@ export const basicProps = {
default: null,
},
ellipsis: { type: Boolean, default: true },
isCanResizeParent: { type: Boolean, default: false },
canResize: { type: Boolean, default: true },
clearSelectOnPageChange: propTypes.bool,
resizeHeightOffset: propTypes.number.def(0),
......
......@@ -191,6 +191,8 @@ export interface BasicTableProps<T = any> {
actionColumn?: BasicColumn;
// 文本超过宽度是否显示。。。
ellipsis?: boolean;
// 是否继承父级高度(父级高度-表单高度-padding高度)
isCanResizeParent?: boolean;
// 是否可以自适应高度
canResize?: boolean;
// 自适应高度偏移, 计算结果-偏移量
......
......@@ -195,5 +195,6 @@ export default {
editCellTable: 'Editable cell',
editRowTable: 'Editable row',
authColumn: 'Auth column',
resizeParentHeightTable: 'resizeParentHeightTable',
},
};
......@@ -186,5 +186,6 @@ export default {
editCellTable: '可编辑单元格',
editRowTable: '可编辑行',
authColumn: '权限列',
resizeParentHeightTable: '继承父元素高度',
},
};
......@@ -239,6 +239,14 @@ const comp: AppRouteModule = {
title: t('routes.demo.table.authColumn'),
},
},
{
path: 'resizeParentHeightTable',
name: 'ResizeParentHeightTable',
component: () => import('/@/views/demo/table/ResizeParentHeightTable.vue'),
meta: {
title: t('routes.demo.table.resizeParentHeightTable'),
},
},
],
},
{
......
<template>
<div class="h-full flex p-4">
<div class="flex flex-col pr-4 w-1/2">
<div class="flex-1">
<BasicTable @register="registerTable" />
</div>
<div class="h-4"></div>
<div class="flex-1">
<BasicTable @register="registerTable" />
</div>
</div>
<div class="flex-1 flex flex-col w-1/2 h-full">
<div class="h-1/3 mb-4">
<BasicTable @register="registerTable" />
</div>
<div class="h-1/3 mb-4">
<BasicTable @register="registerTable2" />
</div>
<div class="h-1/3">
<BasicTable @register="registerTable1" />
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable } from '/@/components/Table';
import { getBasicColumns, getFormConfig } from './tableData';
import { demoListApi } from '/@/api/demo/table';
export default defineComponent({
components: { BasicTable },
setup(_) {
const [registerTable] = useTable({
api: demoListApi,
columns: getBasicColumns(),
useSearchForm: false,
formConfig: getFormConfig(),
showTableSetting: false,
tableSetting: { fullScreen: true },
showIndexColumn: false,
isCanResizeParent: true,
rowKey: 'id',
});
const [registerTable1] = useTable({
api: demoListApi,
columns: getBasicColumns(),
formConfig: getFormConfig(),
showTableSetting: false,
tableSetting: { fullScreen: true },
showIndexColumn: false,
isCanResizeParent: true,
useSearchForm: false,
rowKey: 'id',
});
const [registerTable2] = useTable({
api: demoListApi,
columns: getBasicColumns(),
formConfig: getFormConfig(),
showTableSetting: false,
tableSetting: { fullScreen: true },
showIndexColumn: false,
isCanResizeParent: true,
useSearchForm: false,
pagination: false,
rowKey: 'id',
});
return {
registerTable,
registerTable1,
registerTable2,
};
},
});
</script>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论