一、关于 UseElementSize
UseElementSize 是一个 Vue 组合式 API 的实用工具,通常用于获取 DOM 元素的尺寸信息,例如宽度、高度等。它通常与 v-slot 一起使用,以便在模板中直接访问这些尺寸信息。
地址:https://vueuse.org/core/useElementSize/#useelementsize
安装后使用
npm install @vueuse/core
二、设置表格高度自适应
1.关键代码
<template>
<div class="content-wrap1 p-12 auto-wrap flex flex-col gap-16 bg-white">
<!-- 搜索工具栏 -->
<div class="flex flex-row items-center gap-12"></div>
<!-- 表格内容 -->
<div ref="tableDivRef" class="flex-1">
<el-table
:data="state.tableData"
stripe
border
:max-height="Math.floor(height) - 50"
:header-cell-style="{ textAlign: 'center' }">
<el-table-column
type="index"
:index="formIndex"
width="70"
:label="t('table.index')"
align="center" />
<el-table-column v-for="col of state.headList" :key="col.key" v-bind="getColProps(col)">
</el-table-column>
<el-table-column :label="$t('common.operate')" width="120" align="center">
<template #default="scope">
<el-link
class="mr-10"
type="primary"
:underline="false"
@click="handleEdit(scope.row.id)">
{{ $t('table.btn.edit') }}
</el-link>
<el-link type="danger" :underline="false" @click="handleDelete(scope.row.id)">
{{ $t('table.btn.delete') }}
</el-link>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="flex justify-end mt-16">
<el-pagination
:currentPage="state.page"
:page-size="state.size"
:page-sizes="[15, 20, 30, 40, 50]"
layout="total, sizes, prev, pager, next, jumper"
:total="state.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
</div>
</div>
</template>
<script setup lang="ts">
const tableDivRef = ref(null);
const { height } = useElementSize(tableDivRef);
</script>
<style lang="scss" scoped>
.content-wrap {
position: relative;
padding: 12px;
height: 100%;
width: 100%;
background-color: #fff;
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.02);
display: grid;
grid-template-rows: auto 1fr auto;
gap: 16px;
}
</style>
2.解析
1.给表格的父元素设置高度为页面的剩余部分,并绑定ref
2.使用const { height } = useElementSize(tableDivRef);
获取表格父元素的具体高度
3.给表格设置最大高度,要减去分页的高度::max-height="Math.floor(height) - 50"
三、无渲染组件版本设置表格高度自适应
1.关键代码:
<template>
<div class="table-page-wrap auto-wrap">
<!-- 搜索工具栏部分内容省略 -->
<div></div>
<!-- 表格部分 -->
<UseElementSize v-slot="{ height }">
<el-table
:data="state.tableData"
stripe
border
:max-height="height"
:header-cell-style="{ textAlign: 'center' }">
<el-table-column
type="index"
:index="formIndex"
width="70"
:label="t('table.index')"
align="center" />
<el-table-column v-for="col of state.headList" :key="col.key" v-bind="getColProps(col)">
</el-table-column>
<el-table-column :label="$t('common.operate')" width="120" align="center">
<template #default="scope">
<el-link
class="mr-10"
type="primary"
:underline="false"
@click="handleEdit(scope.row.id)">
{{ $t('table.btn.edit') }}
</el-link>
<el-link type="danger" :underline="false" @click="handleDelete(scope.row.id)">
{{ $t('table.btn.delete') }}
</el-link>
</template>
</el-table-column>
</el-table>
</UseElementSize>
<!-- 分页 -->
<div class="flex justify-end">
<el-pagination
:currentPage="state.page"
:page-size="state.size"
:page-sizes="[15, 20, 30, 40, 50]"
layout="total, sizes, prev, pager, next, jumper"
:total="state.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
</div>
</template>
<script setup lang="ts"></script>
<style lang="scss" scoped>
.table-page-wrap {
position: relative;
padding: 12px;
height: 100%;
width: 100%;
background-color: #fff;
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.02);
display: grid;
// https://stackoverflow.com/a/52380579/7652034
grid-template-rows: auto 1fr auto;
gap: 16px;
}
</style>
2.解析
模板部分:
< UseElementSize v-slot="{ height }">
: 使用 v-slot 插槽来接收 UseElementSize 提供的尺寸信息。这里我们只关心 height,也可以获取其他属性如 width。
:max-height="height"
: 将列表的最大高度设置为 height
3.遇到的问题
问题1: 表格内容超出时整个页面会显示滚动条
https://github.com/w3c/csswg-drafts/issues/1777
原因是表格父级容器高度计算不正确,1fr 实际上是 minmax(auto, 1fr)的缩写, auto可能会导致内容大于1fr的情况
解决方法:
修改table-page-wrap 样式
grid-template-rows: auto minmax(0, 1fr) auto;
问题2:表格高度显示小数导致无法正常滚动
解决方法
修改表格最大高度设置: :max-height="Math.floor(height || 0)"