【实践功能记录8】使用UseElementSize实现表格高度自适应

一、关于 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)"

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值