Browse Source

fix: table overflow and pagination visibility with large page sizes

- Add height="0" to el-table and CSS flex layout to prevent overflow
- Add overflow:hidden and explicit height constraints to .root-container and .app-main
- Move inline style bindings to scoped CSS with v-bind()
- Bind height/maxHeight props to .list-table container style for configurability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dev
hechang27-sprt 3 months ago
parent
commit
cba11efd7e
  1. 157
      packages/base/data/list-table.vue
  2. 33
      packages/manage/router/index.vue
  3. 35
      packages/manage/router/zhuBeiDong.vue

157
packages/base/data/list-table.vue

@ -1,61 +1,64 @@ @@ -1,61 +1,64 @@
<template>
<div class="my-table">
<el-table
ref="table"
:size="state.size.size"
:data="page ? data.data : data"
:border="border"
@selection-change="selectionChange"
@row-click="emit('row-click', $event)"
@cell-click="(row, column, cell, event) => emit('cell-click', row, column, cell, event)"
:height="height || (page ? state.size.pTableHeight : state.size.tableHeight)"
highlight-current-row
:row-key="rowKey"
:tree-porps="treeProps"
:lazy="lazy"
:load="load"
>
<el-table-column
v-for="item in props"
:key="item.code"
:prop="item.code"
:label="item.name || t(item.i18n)"
:type="item.type"
:min-width="item.width"
:width="item.type ? item.width : ''"
:fixed="item.fixed"
:align="item.align ? item.align : 'center'"
show-overflow-tooltip
:formatter="(row: any, column: any, value: any) => formatter(row, column, value, item)"
<div class="list-table" :style="containerStyle">
<div class="my-table">
<el-table
ref="table"
:size="state.size.size"
height="0"
:fit="true"
:data="page ? data.data : data"
:border="border"
@selection-change="selectionChange"
@row-click="emit('row-click', $event)"
@cell-click="(row, column, cell, event) => emit('cell-click', row, column, cell, event)"
highlight-current-row
:row-key="rowKey"
:tree-porps="treeProps"
:lazy="lazy"
:load="load"
>
<template v-if="item.slot" #default="{ row }">
<slot :name="item.code" :row="row"></slot>
</template>
<template v-if="item.dict" #default="{ row }">
{{ formatterByDist(item.dict, lodash.get(row, item.code)) }}
</template>
</el-table-column>
</el-table>
</div>
<div v-if="page" class="my-pagination">
<el-pagination
:small="state.size.size == 'small'"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="example.page"
:page-sizes="[10, 20, 50, 100, 200]"
:page-size="example.size"
layout="total, sizes, prev, pager, next, jumper"
:total="data.total"
>
</el-pagination>
<el-table-column
v-for="item in props"
:key="item.code"
:prop="item.code"
:label="item.name || t(item.i18n)"
:type="item.type"
:min-width="item.width"
:width="item.type ? item.width : ''"
:fixed="item.fixed"
:align="item.align ? item.align : 'center'"
show-overflow-tooltip
:formatter="(row: any, column: any, value: any) => formatter(row, column, value, item)"
>
<template v-if="item.slot" #default="{ row }">
<slot :name="item.code" :row="row"></slot>
</template>
<template v-if="item.dict" #default="{ row }">
{{ formatterByDist(item.dict, lodash.get(row, item.code)) }}
</template>
</el-table-column>
</el-table>
</div>
<div v-if="page" class="my-pagination">
<el-pagination
:small="state.size.size == 'small'"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="example.page"
:page-sizes="[10, 20, 50, 100, 200]"
:page-size="example.size"
layout="total, sizes, prev, pager, next, jumper"
:total="data.total"
>
</el-pagination>
</div>
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref, watch, onUpdated } from "vue";
import { reactive, onMounted, ref, watch, onUpdated, computed } from "vue";
import { useI18n } from "vue3-i18n";
import { TableColumn } from "noob-mengyxu";
import * as lodash from "lodash-es";
@ -64,11 +67,23 @@ const { t } = useI18n(); @@ -64,11 +67,23 @@ const { t } = useI18n();
const { state } = useStore();
const table = ref();
const containerStyle = computed(() => {
const style: Record<string, string> = {};
if (prop.height !== undefined) {
style.height = typeof prop.height === "number" ? `${prop.height}px` : String(prop.height);
}
if (prop.maxHeight !== undefined) {
style.maxHeight = typeof prop.maxHeight === "number" ? `${prop.maxHeight}px` : String(prop.maxHeight);
}
return style;
});
interface Props {
data?: any;
props?: TableColumn[];
page?: boolean;
height?: number;
height?: number | string;
maxHeight?: number | string;
example?: any;
rowKey?: string;
selectKey?: string;
@ -82,6 +97,7 @@ const prop = withDefaults(defineProps<Props>(), { @@ -82,6 +97,7 @@ const prop = withDefaults(defineProps<Props>(), {
props: () => [],
page: false,
height: undefined,
maxHeight: undefined,
example: () => ({}),
rowKey: undefined,
selectKey: undefined,
@ -177,6 +193,31 @@ onUpdated(() => { @@ -177,6 +193,31 @@ onUpdated(() => {
});
</script>
<style lang="scss" scoped>
.list-table {
display: flex;
flex-direction: column;
flex: 1;
overflow: hidden;
}
.my-table {
flex: 1;
width: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.my-table .el-table {
height: 100% !important;
display: flex;
flex-direction: column;
}
.my-table .el-table__inner-wrapper {
height: 100% !important;
}
.my-table * {
--el-table-bg-color: v-bind("state.style.tableBg") !important;
--el-table-tr-bg-color: v-bind("state.style.tableBg") !important;
@ -192,15 +233,21 @@ onUpdated(() => { @@ -192,15 +233,21 @@ onUpdated(() => {
--el-bg-color: v-bind("state.style.tableBg") !important;
}
::v-deep .el-table__row--level-1,
::v-deep .el-table__row--level-3 {
.list-table :deep(.el-table__row--level-1),
.list-table :deep(.el-table__row--level-3) {
background: v-bind("state.style.tableChildBg") !important;
}
::v-deep .el-table .el-table__cell {
.list-table :deep(.el-table .el-table__cell) {
padding: v-bind("state.size.tablePad");
}
.my-pagination {
display: flex;
justify-content: center;
padding-top: 5px;
}
.my-pagination * {
--el-pagination-bg-color: v-bind("state.style.bodyBg") !important;
--el-pagination-disabled-bg-color: v-bind("state.style.bodyBg") !important;

33
packages/manage/router/index.vue

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
<template>
<el-container :style="appMain" ref="main" v-show="!flag.loading">
<el-container ref="main" v-show="!flag.loading" class="root-container">
<el-header v-show="state.size.headHeight != '0px'" class="app-head" :height="state.size.headHeight">
<Head :title="title" :logo="logo" :username="username">
<template #left>
@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
</template>
<script lang="ts" setup>
import { onBeforeUnmount, onMounted, reactive, ref, watch } from "vue";
import { onBeforeUnmount, onMounted, reactive, ref, watch, computed } from "vue";
import { useStore } from "vuex";
import { useRouter, useRoute } from "vue-router";
import { Api, NoobHead } from "noob-mengyxu";
@ -36,10 +36,6 @@ const { state, commit, dispatch } = useStore(); @@ -36,10 +36,6 @@ const { state, commit, dispatch } = useStore();
const emit = defineEmits(["updatePwd", "logout"]);
const router = useRouter();
const route = useRoute();
const appMain = reactive({
height: window.innerHeight + "px",
backgroundColor: state.style.bodyBg,
});
const main = ref();
const flag = reactive({
showHeader: true,
@ -97,7 +93,6 @@ const props = defineProps({ @@ -97,7 +93,6 @@ const props = defineProps({
const onResize = () => {
const height = window.innerHeight;
appMain.height = height + "px";
commit("initSize", [height, window.innerWidth]);
};
@ -163,7 +158,7 @@ body { @@ -163,7 +158,7 @@ body {
font-size: v-bind("state.size.fontSize") !important;
font-family: "Microsoft YaHei";
width: 100%;
height: 100%;
min-height: 100vh;
overflow: hidden;
padding: 0px;
margin: 0px;
@ -171,12 +166,32 @@ body { @@ -171,12 +166,32 @@ body {
</style>
<style lang="scss" scoped>
.root-container {
min-height: 100vh !important;
height: 100vh !important;
max-height: 100vh !important;
display: flex !important;
flex-direction: column !important;
overflow: hidden !important;
background-color: v-bind("state.style.bodyBg");
}
#container {
flex: 1 1 auto !important;
min-height: 0 !important;
overflow: hidden !important;
}
.app-main {
box-shadow: 2px 2px 5px 3px #e5e6eb;
border-radius: 4px;
margin: 0px 0px 0px 3px !important;
padding: 0 !important;
height: v-bind("state.size.mainHeight");
flex: 1 1 auto !important;
min-height: 0 !important;
display: flex !important;
flex-direction: column !important;
overflow: hidden !important;
}
.el-header,

35
packages/manage/router/zhuBeiDong.vue

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
<template>
<el-container :style="appMain" ref="main" v-show="!flag.loading">
<el-container ref="main" v-show="!flag.loading" class="root-container">
<el-aside :width="state.size.asideWidth">
<MenuTree :title="title || t('title')" :logo="logo" :data="menus" mode="vertical" />
</el-aside>
@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
</template>
<script lang="ts" setup>
import { reactive, onMounted, ref, onBeforeUnmount } from "vue";
import { reactive, onMounted, ref, onBeforeUnmount, computed } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { NoobHead, Api, Styles, Size } from "noob-mengyxu";
@ -36,10 +36,6 @@ const { t } = useI18n(); @@ -36,10 +36,6 @@ const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const emit = defineEmits(["updatePwd", "logout"]);
const router = useRouter();
const appMain = reactive({
height: window.innerHeight + "px",
backgroundColor: state.style.bodyBg,
});
const main = ref();
const flag = reactive({
showHeader: true,
@ -90,7 +86,6 @@ const props = defineProps({ @@ -90,7 +86,6 @@ const props = defineProps({
const onResize = () => {
const height = window.innerHeight;
appMain.height = height + "px";
commit("initSize", [height, window.innerWidth]);
};
@ -143,20 +138,40 @@ body { @@ -143,20 +138,40 @@ body {
font-size: v-bind("state.size.fontSize") !important;
font-family: "Microsoft YaHei";
width: 100%;
height: 100%;
overflow: hidden;
min-height: 100vh;
overflow-x: hidden;
padding: 0px;
margin: 0px;
}
</style>
<style lang="scss" scoped>
.root-container {
min-height: 100vh !important;
height: 100vh !important;
max-height: 100vh !important;
display: flex !important;
flex-direction: column !important;
overflow: hidden !important;
background-color: v-bind("state.style.bodyBg");
}
#container {
flex: 1 1 auto !important;
min-height: 0 !important;
overflow: hidden !important;
}
.app-main {
box-shadow: 2px 2px 5px 3px #e5e6eb;
border-radius: 4px;
margin: 0px 0px 0px 3px !important;
padding: 0 !important;
height: v-bind("state.size.mainHeight");
flex: 1 1 auto !important;
min-height: 0 !important;
display: flex !important;
flex-direction: column !important;
overflow: hidden !important;
}
.el-header,

Loading…
Cancel
Save