table表格自适应浏览器窗口变化解决方案

前言

大家好,本文聊一下在做后台管理系统项目时,表格高度自适应的css解决方案,使表格能根据浏览器窗口变化自适应调节高度、自动适应内容高度来显示表格滚动条。本文基于vue3+element-plus 组件库进行开发,主要涉及到flex布局 、以及BFC特性

BFC简要介绍

BFC,即块格式化上下文(Block Formatting Context),是CSS中的一个概念,用于描述Web页面中块级元素布局的一种规则。BFC是一种独立的渲染区域,具有一套渲染规则,决定了其中元素如何布局、相互影响以及与外部元素的关系。

BFC的主要特性包括:

  1. 包含块:BFC会创建一个包含块,它决定了BFC内部元素的布局。通常情况下,包含块是指最近的块级祖先元素,但也可以通过设置某些CSS属性(如float、position等)将其改变。
  2. 垂直方向上的布局:在BFC中,垂直方向的边距(margin)会发生折叠(合并),这意味着相邻的块级元素的上下边距可能会变得较小,从而影响它们的布局。
  3. 清除浮动:当一个元素浮动时,它会脱离正常的文档流,可能导致父元素的高度塌陷。而在BFC中,浮动元素会被包含在内部,从而解决了这个问题。
  4. 阻止外部元素的影响:BFC会创建一个隔离的环境,使得BFC内部元素与外部元素相互独立,不会相互影响。

布局设计

layout.vue文件

js 复制代码
<template>
  <el-container>
    <el-aside width="200px">Aside</el-aside>
    <el-container>
      <el-header>Header</el-header>
      <el-main>Main</el-main>
    </el-container>
  </el-container>
</template>

<script setup lang="ts">

</script>

<style scoped>
.el-aside {
  background-color: #D9ECFF;
}
.el-header {
  background-color: #C6E2FF;
}
.el-main {
  background-color: #ECF5FF;
}
</style>

布局如下图所示:

接下来把el-container容器设置为height: 100vh;vh是一个相对单位,表示视口高度的百分比。 这里即把容器高度设置为相对于浏览器窗口显示网页内容的部分视图的100%。

css 复制代码
.el-container {
  height: 100vh;
}

现在已经使铺满屏幕了,如下图所示:

我们的路由一般展示在main区域,下面开始创建一个表格数据展示页面,页面支持筛选查询以及分页。

page.vue

js 复制代码
<template>
  <div class="flex-box">
    <!-- 封装的筛选表单 -->
    <FilterForm />
    <!-- 封装的表格组件 -->
    <Table class="flex-1" :data="tableData">
      <el-table-column prop="date" label="Date" width="180" />
      <el-table-column prop="name" label="Name" width="180" />
      <el-table-column prop="address" label="Address" />
      <el-table-column label="操作">
        <el-button @click="to">查看</el-button>
      </el-table-column>
    </Table>
  </div>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'
import FilterForm from '@/components/FilterForm/FilterForm.vue'
import Table from '@/components/Table/Table.vue'

const router = useRouter()

const tableData: any[] = []
for(let i = 0; i < 100; i++) {
  tableData.push({
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  })
}

const to = () => {
  router.push('/user/1')
}
</script>

Table.vue组件

js 复制代码
<template>
  <div class="table-box">
    <el-table :data="data" border style="width: 100%">
      <slot></slot>
    </el-table>
    <!-- 封装的页码组件 -->
    <Pagination :total="data.length"/>
  </div>
</template>

页面效果如下:

这里可以看到在main区域出现了滚动条,而我们想要的效果外部布局容器不显示滚动条,只在表格内容区域出现滚动条,并且固定表头。

首先查看如何实现固定表头,查阅element-plus官方文档固定表头只需设置height高度即可:

但是,我们现在想要实现的是根据浏览器窗口大小自动计算出表格高度,实现方法之一可以通过js动态计算视口高度,但这也存在一定的性能消耗,所以这里介绍另一种解决方案,即使用CSS3引入的flex自适应布局来实现动态计算高度。

回到刚刚创建的page.vue 页面,在页面根标签divTable组件 分别添加flex-boxhidden类及样式:

js 复制代码
<template>
  <div class="flex-box">
    <!-- 封装的筛选表单 -->
    <FilterForm />
    <!-- 封装的表格组件 -->
    <Table class="hidden" :data="tableData">
      <el-table-column prop="date" label="Date" width="180" />
      <el-table-column prop="name" label="Name" width="180" />
      <el-table-column prop="address" label="Address" />
      <el-table-column label="操作">
        <el-button @click="to">查看</el-button>
      </el-table-column>
    </Table>
  </div>
</template>
css 复制代码
.flex-box {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.flex-1 {
  overflow: hidden;
}

.flex-box继承main的高度,并且开启column方向的flex布局,再给包裹el-table组件的div标签设置overflow: hidden;触发BFC 特性,隐藏子元素高度溢出部分,并使其高度不会被子元素的高度影响,使其高度能够自适应flex-box容器下的剩余空间。这里不选择增加flex:1;样式的目的是,考虑到表格数据较少不足以铺满剩余空间时,出现的白边情况。

增加flex: 1;效果如下图所示:

没有flex: 1;效果如下图所示:

目前,包裹表格和页码容器高度 已经可以自适应,但是el-table表格 高度还没做自适应,所以表格高度溢出也导致页码被挤出容器被隐藏了,所以进来Table.vue表格组件设置一下样式

css 复制代码
.table-box {
  display: flex;
  flex-direction: column;
}
.el-table {
  flex: 1;
  overflow: hidden;
}

这里主要也是为el-table表格 设置overflow: hidden;使其能够自适应table-box的剩余空间,即减去页码组件高度所剩空间,如何不设置表格将占满父容器高度,页码将被溢出而被隐藏。

最终效果图,如下所示

总结

以上表格自适应高度主要考察flex布局,以及通过为父元素设置overflow: hidden;触发BFC的特性,使得BFC内部元素(即子元素)与外部元素相互独立,不会相互影响,防止子元素高度溢出时撑开父容器,影响flex布局无法正常自适应问题。

往期文章回顾

一文学会请求中断、请求重发、请求排队、请求并发

一文学会vue3如何自定义hook钩子函数和封装组件

都2023了,还不会开发一个属于自己的组件库?

相关推荐
vvilkim34 分钟前
Flutter 导航与路由管理:Navigator 的深入解析与实践
前端·javascript·flutter
vvilkim36 分钟前
Flutter状态管理进阶:从基础到架构设计
前端·flutter
唐人街都是苦瓜脸1 小时前
pnpm install 和 npm install 的区别
前端·npm·node.js
戒不掉的伤怀1 小时前
react,使用echarts过程
前端·react.js·echarts
小白探索世界欧耶!~1 小时前
react 使用 postcss-px-to-viewport 实现 px 自动转 vw 自适应
前端·javascript·vue.js·程序人生·react.js·postcss
ryipei1 小时前
vue纯前端根据页面或者后台数据,读取本地文档模板,填充数据后并导出
前端·javascript·vue.js
Gazer_S2 小时前
【Web 应用缓存与部署优化指南】
前端·缓存
老李笔记2 小时前
VUE element table 列合并
javascript·vue.js·ecmascript
滿2 小时前
Vue3 Element Plus 表格默认显示一行
javascript·vue.js·elementui
好了来看下一题2 小时前
TypeScript 项目配置
前端·javascript·typescript