vue3.0 elementplus el-table自定义指令自动计算table高度 及分页大小

一、自定义指令

* 创建table-auto-height.ts 文件* 
import {h, nextTick, render} from "vue";
import {ElTable, ElTableColumn} from "element-plus";
export default (app: any) => {
    //自定义组件
    app.directive('table-auto-height', {
            async created(el: any, binding: any, vnode, prevVnode) {
                let tableCol = [];
                //组合table
                for (const appElement of vnode.dynamicChildren[0].children) {
                    //获取表头 及其 原有插槽
                    tableCol.push({props: appElement.props, children: appElement.children})
                }
                await creatTable(tableCol, el, binding);
            }
        }
    )
}
const getNextSiblings = (element: any) => {
    let siblings = [];
    while (element.nextElementSibling) {
        element = element.nextElementSibling;
        if (element.nodeType === 1 && element !== document.body) {
            siblings.push(element);
        }
    }
    return siblings;
}

const getPreviousSiblings = (element: any) => {
    let siblings = [];
    while (element.previousElementSibling) {
        element = element.previousElementSibling;
        if (element.nodeType === 1 && element !== document.body) {
            siblings.push(element);
        }
    }
    return siblings;
}

const extractedNumber = (str) => {
    const match = str.match(/\d+(\.\d+)?/);
    return match ? parseFloat(match[0]) : 0;
}

const creatTable = async (columns, el, binding) => {
    //默认存在一个元素用来动态计算pagesizs
    const tableData = [{}]
    const colunsSolt = (column) => {
        let result = {};
        if (column.children) {
            result = column.children;
        }
        if (column.childColumns) {
            result = {default: () => createColumns(column.childColumns)}
        }
        return result;

    }
    const createColumns = (columns) => {
        if (!columns.length) return undefined
        return columns.map(column => {
            return h(ElTableColumn, {...column.props,show:false},
                colunsSolt(column)
            )
        })
    }
    let div = document.createElement("div");
    div.id = Math.random().toString(36).slice(-6);
    let eltableVnode = h(ElTable, {
            data: tableData
        }, () => createColumns(columns)
    );
    render(eltableVnode, div)
    el.appendChild(div)
    //必须为两个await await 确保 eltable 完全渲染之后 在执行以下代码  防止获取table高度不正确
    await await nextTick();
    let eltableDom = document.getElementById(div.id);
    // 获取表头高度
    let hiddenHeaderHeight=eltableDom.querySelector(".el-table__header").getBoundingClientRect().height;
    let tableHeaderHeightPx = window.getComputedStyle(eltableDom.querySelector(".el-table__header")).height;
    let tableHeaderHeight = extractedNumber(tableHeaderHeightPx)
    //获取行高度el-table__body > el-table__row
    let tableBodyTrHeightPx = window.getComputedStyle(eltableDom.querySelector(".el-table__body  .el-table__row")).height;
    let tableBodyTrHeight = extractedNumber(tableBodyTrHeightPx)
    let clientHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
    let nextSiblings = getNextSiblings(el);
    let previousSiblings = getPreviousSiblings(el)
    let result = [...nextSiblings, ...previousSiblings];
    result.forEach(res => {
        clientHeight -= res.clientHeight;
    })
    let pageSize = Math.floor((clientHeight - tableHeaderHeight) / tableBodyTrHeight)
    binding.value.pageSize = pageSize
    el.style.height = pageSize * tableBodyTrHeight + tableHeaderHeight + "px";
    div.style.display = "none"
}

二、全局指令注册

main.ts 注册全局指令

const app = createApp(App)
import tableAutoHeight from "@/directive/table-auto-height.ts";
tableAutoHeight(app)

三、组件使用

<template>
  <el-table :data="tableData"  stripe  v-table-auto-height:pagination="pagination" show-overflow-tooltip >
    <el-table-column type="index" min-width="55" label="序号"/>
  </el-table>
</template>

<script setup lang="ts">
import { onMounted, reactive} from "vue";
onMounted(() => {
	await await nextTick()
  searchForm(1)
})
let pagination = reactive({
  pageSize: 0,
  pageNum: 1
})
let tableData = reactive([]) as any;
const searchForm = (num: any) => {
	console.log(pagination.pageSize)
}
</script>

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js 是一个流行的JavaScript框架,它的数据绑定和组件化特性使得开发动态Web应用变得更加容易。其中,强大的UI组件库(如Element,iView等)能够极大地提高Web应用开发效率。而el-table是一种用于展示表格数据的组件,它拥有可排序、过滤、分页等多种功能。本文主要介绍如何使用Vue.js实现el-table表头自定义。 在Vue.js中使用el-table组件时,表头(thead)用于显示列名和控制排序、过滤等操作。默认情况下,el-table组件根据数据源中的列名自动生成表头。若需自定义表头,可通过以下方式实现: 1. 使用el-table-column组件 在el-table中使用el-table-column组件可以实现自定义表头。具体操作如下: ```html <el-table :data="tableData"> <el-table-column prop="date" label="日期"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> </el-table> ``` 上述代码中,我们为el-table添加了三个el-table-column组件,分别对应表格中的三列数据。同时,我们在每个el-table-column组件上指定了prop和label属性,其中prop属性指定了对应的数据源中的字段名,label属性指定了表头标题。 2. 使用Scoped Slots 如果需要实现更加复杂的表头,可以使用Scoped Slots进行自定义。具体操作如下: ```html <el-table :data="tableData"> <template slot="header"> <el-row> <el-col :span="8">日期</el-col> <el-col :span="8">姓名</el-col> <el-col :span="8">地址</el-col> </el-row> </template> <el-table-column prop="date"></el-table-column> <el-table-column prop="name"></el-table-column> <el-table-column prop="address"></el-table-column> </el-table> ``` 上述代码中,我们使用了el-table的header slot,它可以让我们自定义表头,即在表头中添加任意HTML代码。在header slot中我们使用了el-row和el-col组件创建了一个表头行,然后通过span属性设置每列所占的宽度,最终实现了自定义表头。 总结 以上就是Vue.js实现el-table表头自定义的两种方式。使用el-table-column组件可以快速地实现简单的自定义表头,而使用Scoped Slots可以实现更加复杂的表头需求。选择合适的方式,可以大大提高开发效率和表格的可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值