实现列表自适应布局并支持滚动
在B端系统开发中,我们常常需要设计一种布局,其中搜索区域高度不定,列表内容不多的时候则自适应,列表内容过多时占据剩余空间,并且当列表内容溢出时能够滚动。以下是实现这种布局的一种方法。
列表内容不多时,高度自适应。
列表内容超过剩余空间时则撑满空间,内部滚动。
一、布局分析
这种布局主要包含两个部分:搜索区域和列表区域。搜索区域的高度根据内容动态变化,而列表区域则需要自适应地占据剩余空间。当列表内容超出可见区域时,列表区域会出现滚动条以便用户查看全部内容。
要实现el-table内部滚动,则el-table必须有一个height或者max-height。如果要通过el-table的props设定高度则必须获取高度值,那么只能设置固定高度或者通过js计算,这种方法并不灵活。
如果用css的flex布局实现就简单多了,而且可以实现一个通用的布局组件。
- 首先固定最外层组件的高度
height: calc(100vh - var(--soy-header-height) - var(--soy-tab-height));。 - 然后设置最外层组件布局为
display: flex; flex-direction: column;,这样使得搜索区域高度不定的前提下,表格区域高度自适应且不会溢出。 - 最后设置表格区域为
overflow: hidden; display: flex; flex-direction: column,保证表格区域不会溢出,并且表格区域内部还是一样自适应布局,这样表格区域内部的el-table组件高度会自适应并且固定。当表格内容超过el-table高度时,从而可以触发内部scroll。
二、实现方法
封装一个TableLayout布局组件,插槽插入ElTable就可以实现自适应。
1.实现代码
<script setup lang="ts">
import Main from './Main.vue';
import ContentCard from './ContentCard.vue';
const props = withDefaults(
defineProps<{
contentHeightFixed?: boolean;
}>(),
{
contentHeightFixed: false
}
);
</script>
<template>
<Main :class="props.contentHeightFixed ? 'wrapper-height-fixed' : ''" class="search-content">
<ContentCard v-if="$slots.search" class="search-content-form">
<slot name="search"></slot>
</ContentCard>
<ContentCard v-if="$slots.content" :class="props.contentHeightFixed ? 'content-height-fixed' : ''">
<slot name="content"></slot>
</ContentCard>
<slot></slot>
</Main>
</template>
<style lang="scss" scoped>
.search-content {
display: flex;
flex-direction: column;
gap: 16px;
padding: 20px;
&-form {
// 统一搜索表单样式
padding: 20px 16px 10px 16px;
:deep(.el-form) {
padding: 0px;
.el-form-item {
margin-bottom: 10px;
margin-right: 10px !important;
}
}
}
}
.wrapper-height-fixed {
height: calc(100vh - var(--soy-header-height) - var(--soy-tab-height));
}
.content-height-fixed {
overflow: hidden;
display: flex;
flex-direction: column;
}
</style>
4.组件使用
三、关键点说明
- Flex 布局:使用
display: flex和flex-direction: column使容器内的子元素(搜索区域和列表区域)在垂直方向上排列。这样可以方便地让列表区域占据剩余空间。 - 剩余空间占据:flex布局默认各元素flex为1,使表格区域能够自动占据剩余空间,并且表格区域overflow:hidden,保证不会溢出。
- 滚动实现:对于列表区域同样使用
display: flex和flex-direction: column,使得el-table高度自适应并且有一个固定的值(flex布局自动计算),触发内部scroll。
四、总结
采用 Flex 布局可以很方便地实现搜索区域高度不定、列表自适应占据剩余位置并且列表可滚动的布局。这种布局方式不仅代码简洁,而且具有良好的兼容性和可维护性。通过合理设置 CSS 样式和利用 Vue 的动态绑定特性,可以轻松实现复杂布局需求。