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

news/2024/7/7 20:03:25

一、自定义指令

* 创建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>


http://lihuaxi.xjx100.cn/news/1805475.html

相关文章

快速集成Skywalking 9(Windows系统、JavaAgent、Logback)

目录 一、Skywalking简介二、下载Skywalking服务端三、安装Skywalking服务端3.1 解压安装包3.2 启动Skywalking 四、关于Skywalking服务端更多配置五、Java应用集成skywalking-agent.jar5.1 下载SkyWalking Java Agent5.2 集成JavaAgent5.3 Logback集成Skywalking5.4 集成效果 …

ESP32网络开发实例-非接触式水位监测

非接触式水位监测 文章目录 非接触式水位监测1、HC-SR04介绍2、软件准备3、硬件准备4、代码实现在本文中,我们将使用 HC-SR04 超声波传感器和 ESP32 创建一个水位监测网络服务器。 这将是一个非接触式水位测量系统。 首先,我们将介绍HC-SR04 与 ESP32 连接。 使用ESP32对超声…

Canal+Kafka实现MySQL与Redis数据同步(一)

CanalKafka实现MySQL与Redis数据同步&#xff08;一&#xff09; 前言 在很多业务情况下&#xff0c;我们都会在系统中加入redis缓存做查询优化。 如果数据库数据发生更新&#xff0c;这时候就需要在业务代码中写一段同步更新redis的代码。 这种数据同步的代码跟业务代码糅合…

Systemverilog中Clocking blocks

1. clocking block的作用 Clocking block可以将timing和synchronization detail从testbench的structural、functional和procedural elements中分离出来&#xff0c;因此sample timming和clocking block信号的驱动会隐含相对于clocking block的clock了&#xff0c;这就使得对一些…

掌握深度学习利器——TensorFlow 2.x实战应用与进阶

掌握深度学习利器——TensorFlow 2.x实战应用与进阶 摘要&#xff1a;随着人工智能技术的飞速发展&#xff0c;深度学习已成为当下最热门的领域之一。作为深度学习领域的重要工具&#xff0c;TensorFlow 2.x 备受关注。本文将通过介绍TensorFlow 2.x的基本概念和特性&#xff…

C++ 20类型转换指南:使用场景与最佳实践

C 20类型转换指南&#xff1a;使用场景与最佳实践 类型转换 (Casts) C 提供了五种特定的类型转换&#xff1a;const_cast<>()、static_cast<>()、reinterpret_cast<>()、dynamic_cast<>() 和 C20 引入的 std::bit_cast<>()。 请注意&#xff…

TableUtilCache:针对CSV表格进行的缓存

TableUtilCache:针对CSV表格进行的缓存 文件结构 首先来看下CSV文件的结构&#xff0c;如下图&#xff1a; 第一行是字段类型&#xff0c;第二行是字段名字&#xff1b;再往下是数据。每个元素之间都是使用逗号分隔。 看一下缓存里面存储所有表数据的字段 如下图&#xff…

记录联系ThinkPad T490扬声器无声音但插耳机有声音的解决办法

型号&#xff1a;联想ThinkPad T490&#xff0c;系统Win10 64位。 现象&#xff1a;扬声器无声音&#xff0c;插耳机有声音。且右下角小喇叭正常&#xff0c;设备管理器中驱动显示一切也都正常&#xff08;无黄色小叹号&#xff09;。 解决办法&#xff1a; 尝试了各种方法&a…