实现列表自适应布局并支持滚动

在B端系统开发中,我们常常需要设计一种布局,其中搜索区域高度不定,列表内容不多的时候则自适应,列表内容过多时占据剩余空间,并且当列表内容溢出时能够滚动。以下是实现这种布局的一种方法。

列表内容不多时,高度自适应。 image.png 列表内容超过剩余空间时则撑满空间,内部滚动。

一、布局分析

这种布局主要包含两个部分:搜索区域和列表区域。搜索区域的高度根据内容动态变化,而列表区域则需要自适应地占据剩余空间。当列表内容超出可见区域时,列表区域会出现滚动条以便用户查看全部内容。

要实现el-table内部滚动,则el-table必须有一个height或者max-height。如果要通过el-table的props设定高度则必须获取高度值,那么只能设置固定高度或者通过js计算,这种方法并不灵活。

如果用css的flex布局实现就简单多了,而且可以实现一个通用的布局组件。

  1. 首先固定最外层组件的高度height: calc(100vh - var(--soy-header-height) - var(--soy-tab-height));

  2. 然后设置最外层组件布局为display: flex; flex-direction: column;,这样使得搜索区域高度不定的前提下,表格区域高度自适应且不会溢出。

  3. 最后设置表格区域为 overflow: hidden; display: flex; flex-direction: column,保证表格区域不会溢出,并且表格区域内部还是一样自适应布局,这样表格区域内部的el-table组件高度会自适应并且固定。当表格内容超过el-table高度时,从而可以触发内部scroll。

二、实现方法

封装一个TableLayout布局组件,插槽插入ElTable就可以实现自适应。

1.实现代码

<script setup>
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' : ''">
    <ContentCard v-if="$slots.search">
      <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 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.组件使用

三、关键点说明

  1. Flex 布局:使用 display: flexflex-direction: column 使容器内的子元素(搜索区域和列表区域)在垂直方向上排列。这样可以方便地让列表区域占据剩余空间。

  2. 剩余空间占据:flex布局默认各元素flex为1,使表格区域能够自动占据剩余空间,并且表格区域overflow:hidden,保证不会溢出。

  3. 滚动实现:对于列表区域同样使用 display: flexflex-direction: column ,使得el-table高度自适应并且有一个固定的值(flex布局自动计算),触发内部scroll。

四、总结

采用 Flex 布局可以很方便地实现搜索区域高度不定、列表自适应占据剩余位置并且列表可滚动的布局。这种布局方式不仅代码简洁,而且具有良好的兼容性和可维护性。通过合理设置 CSS 样式和利用 Vue 的动态绑定特性,可以轻松实现复杂布局需求。