vue3封装Element Plus table表格组件

news2025/2/22 6:35:03

支持绝大部分Element Plus原有设置属性,支持分页,支持动态适配高度

 效果展示

 

组件代码: 
<template>
  <div class="table-wrap" ref="tableWrap">
    <el-table
      class="w100 h100"
      :data="tableInfo.tableData"
      :height="tableHeight"
      v-bind="attrs"
    >
      <!-- 动态生成列 -->
      <template v-for="(item, index) in columns" :key="index">
        <!-- 选择列 -->
        <el-table-column
          v-if="item.type == 'selection'"
          type="selection"
          v-bind="item"
        >
        </el-table-column>

        <!-- 普通列 -->
        <el-table-column v-else-if="!item.subColumns" v-bind="item">
          <template #default="scope">
            <slot :name="item.prop" :scope="scope">
              {{ scope.row[item.prop] }}
            </slot>
          </template>
        </el-table-column>

        <!-- 嵌套列 -->
        <el-table-column v-else v-bind="item">
          <el-table-column
            v-for="(child, childIndex) in item.subColumns"
            :key="childIndex"
            v-bind="child"
          >
            <template #default="scope">
              <slot :name="child.prop" :scope="scope">
                {{ scope.row[child.prop] }}
              </slot>
            </template>
          </el-table-column>
        </el-table-column>
      </template>
    </el-table>
    <el-pagination
      :page-sizes="pageSizes"
      :current-page="page.currentPage"
      :page-size="page.pageSize"
      background
      layout="total, sizes, prev, pager, next, jumper"
      :total="tableInfo.total"
      @size-change="
        handleChangePage({
          currentPage: page.currentPage,
          pageSize: $event,
        })
      "
      @current-change="
        handleChangePage({
          currentPage: $event,
          pageSize: page.pageSize,
        })
      "
    />
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from "vue";

// Props 接收
const { tableInfo, columns, pageSizes, ...props } = defineProps({
  tableInfo: {
    type: Object,
    default: () => {
      return {
        tableData: [],
        total: 0,
      };
    },
  },
  columns: {
    type: Array,
    default: () => [],
  },
  pageSizes: {
    type: Array,
    default: () => [10, 25, 50, 100],
  },
}); 
const emit =  defineEmits(["current-change"]);
// 获取其他绑定属性
const { attrs } = getCurrentInstance();

// 引用
const tableWrap = ref(null);
const tableHeight = ref(50); // 默认高度
let resizeObserver = null;

//分页
const page = ref({
  currentPage: 1,
  pageSize: 10,
});

//函数
const handleChangePage = ({ currentPage, pageSize }) => {
  page.value.currentPage = currentPage;
  page.value.pageSize = pageSize;
  emit("current-change", { currentPage, pageSize});
};

// 动态计算表格高度
const initResizeObserver = () => {
  if (!tableWrap.value) return;
  //   32是分页高度 10和分页的间隔
  resizeObserver = new ResizeObserver(() => {
    tableHeight.value = tableWrap.value.offsetHeight - 32 - 10 || 500;
  });

  resizeObserver.observe(tableWrap.value);
};

// 生命周期
onMounted(() => initResizeObserver());
onUnmounted(() => resizeObserver?.disconnect());
</script>

<style scoped lang="scss">
.table-wrap {
  width: 100%;
  height: 100%;
  overflow: auto; /* 根据需求适配 */
  display: flex;
  flex-direction: column;
  gap: 10px;
}
</style>
使用方法:

 注意由于表格通过ref="tableWrap"获取的高度,然后ref="tableWrap"设置的高度百分百,所以在使用组件的时候注意组件的外层高度如下方的class="universalTable h100"。

但设置双层表头的时候注意需要把二级表头放在subColumns属性中。

table原生属性可直接加在组件上例如“ :border="true"”的写法,属性方法都可支持

<template>
  <div class="universalTable h100">
    <universalTable
      :border="true"
      :columns="columns"
      :tableInfo="tableInfo"
      ref="refTable"
      @current-change="handleCurrentChange"
    >
      <template #name="{ scope }">
        <span>{{ scope.row.name }}</span>
      </template>
    </universalTable>
  </div>
</template>
<script setup name="Index">
import { ref, reactive, nextTick } from "vue";
//表头数据
const columns = ref([
  {
    type: "selection",
  },
  {
    label: "测试",
    subColumns: [
      {
        prop: "date",
        label: "Date",
        width: 100,
      },
    ],
  },
  {
    prop: "name",
    label: "Name",
    width: 120,
  },
  {
    prop: "address",
    label: "Address",
  },
]);
//列表数据
const tableInfo = ref({
  tableData: [
    {
      date: "2016-05-03",
      name: "Tom",
      address: "No. 189, Grove St, Los Angeles",
    },
    {
      date: "2016-05-02",
      name: "Tom",
      address: "No. 189, Grove St, Los Angeles",
    },
    {
      date: "2016-05-04",
      name: "Tom",
      address: "No. 189, Grove St, Los Angeles",
    },
    {
      date: "2016-05-01",
      name: "Tom",
      address: "No. 189, Grove St, Los Angeles",
    },
  ],
  total: 100,
});
//分页数据
const page = ref({
  currentPage: 1,
  pageSize: 10,
});
//获取分页数据
const handleCurrentChange = ({ currentPage, pageSize }) => {
  page.value.currentPage = currentPage;
  page.value.pageSize = pageSize;
};
</script>

<style scoped lang="scss">
.universalTable {
}
</style>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2248175.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElasticSearch学习篇18_《检索技术核心20讲》LevelDB设计思想

目录 一些常见的设计思想以及基于LSM树的LevelDB是如何利用这些设计思想优化存储、检索效率的。 几种常见的设计思想 索引和数据分离减少磁盘IO读写分离分层思想 LevelDB的设计思想 读写分离设计分层设计与延迟合并LRU缓存加速检索 几种常见设计思想 索引与数据分离 索引…

路由器中继与桥接

一 . 背景 现在的路由器大多数已经开始支持多种网络连接模式&#xff0c;以下将以TP-Link迷你无线路由器为例进行展开介绍。在TP-Link迷你无线路由器上一般有AP&#xff08;接入点&#xff09;模式&#xff0c;Router&#xff08;无线路由&#xff09;模式&#xff0c;Repeate…

Bitcoin---P2SH;P2SH举例;P2SH的局限性

文章目录 1. 摘要2. P2SH举例3. P2SH局限性 1. 摘要 Pay-to-Script-Hash (P2SH) 交易输出的开发是为了简化更复杂和功能性脚本的使用&#xff0c;就像需要提供相应签名才能解锁的支付脚本&#xff08;即 P2PKH 脚本&#xff09;一样简单。为了轻松使用此类兑换脚本&#xff0c…

鸿蒙NEXT开发案例:文字转拼音

【引言】 在鸿蒙NEXT开发中&#xff0c;文字转拼音是一个常见的需求&#xff0c;本文将介绍如何利用鸿蒙系统和pinyin-pro库实现文字转拼音的功能。 【环境准备】 • 操作系统&#xff1a;Windows 10 • 开发工具&#xff1a;DevEco Studio NEXT Beta1 Build Version: 5.0.…

ffmpeg视频滤镜:提取缩略图-framestep

滤镜描述 官网地址 > FFmpeg Filters Documentation 这个滤镜会间隔N帧抽取一帧图片&#xff0c;因此这个可以用于设置视频的缩略图。总体上这个滤镜比较简单。 滤镜使用 滤镜参数 framestep AVOptions:step <int> ..FV....... set frame st…

eclipse-git项目提示NO-HEAD

1、出现该问题的过程 本人在用eclipse拉取git代码&#xff0c;刚拉取完&#xff0c;可能还没来得及跟本地的分支合并&#xff0c;电脑就卡动了。无奈只能重启电脑&#xff0c;打开eclipse&#xff0c;maven项目后面就出现了xxx NO-HEAD的提示。 2、问题解决 根据错误提示&am…

力扣hot100-->排序

排序 1. 56. 合并区间 中等 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输…

鱼眼相机模型-MEI

参考文献&#xff1a; Single View Point Omnidirectional Camera Calibration from Planar Grids 1. 相机模型如下&#xff1a; // 相机坐标系下的点投影到畸变图像// 输入&#xff1a;相机坐标系点坐标cam 输出&#xff1a; 畸变图像素点坐标disPtvoid FisheyeCamAdapter::…

Reactor 模式的理论与实践

1. 引言 1.1 什么是 Reactor 模式&#xff1f; Reactor 模式是一种用于处理高性能 I/O 的设计模式&#xff0c;专注于通过非阻塞 I/O 和事件驱动机制实现高并发性能。它的核心思想是将 I/O 操作的事件分离出来&#xff0c;通过事件分发器&#xff08;Reactor&#xff09;将事…

windows下安装wsl的ubuntu,同时配置深度学习环境

写在前面&#xff0c;本次文章只是个人学习记录&#xff0c;不具备教程的作用。个别信息是网上的&#xff0c;我会标注&#xff0c;个人是gpt生成的 安装wsl 直接看这个就行&#xff1b;可以不用备份软件源。 https://blog.csdn.net/weixin_44301630/article/details/1223900…

深入探索 CnosDB 可观测性最佳实践:开篇

随着云计算、微服务、容器化和 DevOps 等技术的迅猛发展&#xff0c;现代软件系统变得愈加复杂和动态。传统的监控手段已经无法满足对系统状态的全面、实时、准确地了解。在这样的背景下&#xff0c;可观测性&#xff08;Observability&#xff09;作为一种新兴的技术理念应运而…

World of Warcraft /script SetRaidTarget(“target“, n, ““) n=8,7,6,5,4,3,2,1,0

魔兽世界执行当前目标标记方法 /script SetRaidTarget("target", n, "") n8,7,6,5,4,3,2,1,0 解析这个lua脚本 D:\Battle.net\World of Warcraft\_classic_\Interface\AddOns\wMarker wMarker.lua /script SetRaidTarget("target", 8, &quo…

[极客大挑战 2019]BabySQL--详细解析

信息搜集 进入界面&#xff1a; 输入用户名为admin&#xff0c;密码随便输一个&#xff1a; 发现是GET传参&#xff0c;有username和password两个传参点。 我们测试一下password点位能不能注入&#xff1a; 单引号闭合报错&#xff0c;根据报错信息&#xff0c;我们可以判断…

信创改造 - TongRDS 替换 Redis

记得开放 6379 端口哦 1&#xff09;首先在服务器上安装好 TongRDS 2&#xff09;替换 redis 的 host&#xff0c;post&#xff0c;passwd 3&#xff09;TongRDS 兼容 jedis # 例如&#xff1a;更改原先 redis 中对应的 host&#xff0c;post&#xff0c;passwd 改成 TongRDS…

Node.js的http模块:创建HTTP服务器、客户端示例

新书速览|Vue.jsNode.js全栈开发实战-CSDN博客 《Vue.jsNode.js全栈开发实战&#xff08;第2版&#xff09;&#xff08;Web前端技术丛书&#xff09;》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com) 要使用http模块&#xff0c;只需要在文件中通过require(http)引入即可。…

springboot项目使用maven打包,第三方jar问题

springboot项目使用maven package打包为可执行jar后&#xff0c;第三方jar会被打包进去吗&#xff1f; 答案是肯定的。做了实验如下&#xff1a; 第三方jar的项目结构及jar包结构如下&#xff1a;&#xff08;该第三方jar采用的是maven工程&#xff0c;打包为普通jar&#xf…

【linux】服务器加装硬盘后如何将其设置为独立硬盘使用

【linux】服务器加装硬盘后如何将其设置为独立硬盘使用 问题描述&#xff1a;本服务器原本使用了两个硬盘作为存储硬盘&#xff0c;同时对这两个硬盘设置了raid1阵列。现在内存不足要进行加载硬盘&#xff0c;新加载的硬盘不设置为raid1&#xff0c;而是将新加装的两个硬盘作为…

win10中使用ffmpeg和MediaMTX 推流rtsp视频

在win10上测试下ffmpeg推流rtsp视频&#xff0c;需要同时用到流媒体服务器MediaMTX 。ffmpeg推流到流媒体服务器MediaMTX &#xff0c;其他客户端从流媒体服务器拉流。 步骤如下&#xff1a; 1 下载MediaMTX github: Release v1.9.3 bluenviron/mediamtx GitHub​​​​​…

【jupyter】linux服务器怎么使用jupyter

从github上拉取的项目包含 jupyter脚本&#xff1a; 直接点击运行按钮弹出窗口&#xff1a; 选择python环境&#xff1a; 这是我下载的插件&#xff1a; 选好环境后点击运行&#xff0c;却弹出提醒窗口&#xff1a; 点击install自动下载&#xff0c;就是速度很慢&…

ubuntu 安装 docker 记录

本文假设系统为 Ubuntu&#xff0c;从 16.04 到 24.04&#xff0c;且通过 APT 命令安装。理论上也其他 Debian 系的操作系统。 WSL 也一样。 感觉 Docker 官方在强推 Docker Desktop&#xff0c;搜索 Docker 安装文档&#xff0c;一不小心就被导航到了 Docker Desktop 的安装页…