Vue3 + TS + Element-Plus 封装的 Table 表格组件

代码中主要增加了3个插槽,operationsStart 从操作栏开头增加按钮,operationsStart 从操作栏结尾增加按钮,还有一个插槽用来自定义列的内容,就是 TableModel里面的Key

<template>
  <el-table
    border
    stripe
    :data="data"
    :height="tableHeight"
    table-layout="fixed"
    :row-key="rowKey"
    :highlight-current-row="highlightCurrentRow"
    :tree-props="treeProps"
    :header-cell-style="{
      background: '#f5f7fa',
      color: '#606266',
      fontSize: '13px',
    }"
    @selection-change="handleSelectionChange"
    :v-loading="loading"
    :row-class-name="tableRowClassName"
    :expand-row-keys="expandRowKeys"
    class="absolute"
  >
    <el-table-column
      v-if="showSelection"
      align="center"
      fixed
      type="selection"
      width="55"
    />
    <el-table-column
      v-for="tableModel in tableModels"
      :key="tableModel.key"
      :prop="tableModel.key"
      :label="tableModel.label"
      :width="tableModel.width"
      :min-width="tableModel.minWidth"
      :align="tableModel.align"
      :header-align="tableModel.headerAlign"
    >
      <template #default="{ row }">
        <slot
          v-if="slots[tableModel.key]"
          :name="tableModel.key"
          v-bind="row"
        ></slot>
        <span v-else>
          {{ row[tableModel.key] }}
        </span>
      </template>
    </el-table-column>
    <el-table-column
      fixed="right"
      label="操作"
      :width="operationsWidth"
      :min-width="minWidth"
      :align="operationsAlign"
      :header-align="operationsHeaderAlign"
      v-if="shoeOperations"
    >
      <template #default="{ row, $index }">
        <slot name="operationsStart" v-bind="row"></slot>
        <el-button
          link
          type="primary"
          :icon="Edit"
          @click="handleEdit(row, $index)"
          :v-hasPerm="editHasPerm"
          v-if="showEditBtn"
          >编辑
        </el-button>
        <el-button
          @click="handleDelete(row, $index)"
          link
          type="danger"
          :icon="Delete"
          v-if="showDeleteBtn"
          :v-hasPerm="deleteHasPerm"
          >删除
        </el-button>
        <slot name="operationsEnd" v-bind="row"></slot>
      </template>
    </el-table-column>
  </el-table>
</template>
<script setup lang="ts">
/*
 * @slot default 插槽
 * operationsStart 从操作栏开头增加按钮
 * operationsStart 从操作栏结尾增加按钮
 * Key TableModel里面的Key,用来自定义列的内容
 * */

import { Delete, Edit } from "@element-plus/icons-vue";

// 【接口】table表格模型
interface ITableModel {
  // 表头显示文字
  label: string;
  // 表格列Keu
  key: string;
  // 表格列宽
  width?: number | string;
  // 表格列显示文字
  value?: string;
  // 表格内容位置
  align?: string;
  // 表格表头位置
  headerAlign?: string;
  // 列最小宽度
  minWidth?: number | string;
}

// 【接口】接受传参字段
interface IProps {
  // 生成表格参数
  tableModels?: ITableModel[];
  // 表格数据
  data: object[];
  // 是否为树形表格
  treeProps?: Object;
  // 加载状态
  loading?: boolean;
  // 表格行Keu
  rowKey?: any;
  // 表格高度
  height?: any;
  // 表格自适应减去的高度
  // eslint-disable-next-line vue/prop-name-casing
  dynamic?: number;
  // 表格单选
  highlightCurrentRow?: boolean;
  // 是否显示编辑按钮
  showEditBtn?: boolean;
  // 是否显示多选框
  showSelection?: boolean;
  // 是否显示删除按钮
  showDeleteBtn?: boolean;
  // 删除权限
  deleteHasPerm?: any;
  // 编辑权限
  editHasPerm?: any;
  // 操作栏宽度
  operationsWidth?: number;
  // 是否显示操作栏
  shoeOperations?: boolean;
  // 操作栏内容位置
  operationsAlign?: string;
  // 操作栏头部位置
  operationsHeaderAlign?: string;
  // 操作栏最小宽度
  minWidth?: number | string;
  // 树表格时默认展开参数
  expandRowKeys?: any;
}

// 【接口】分页
interface IPage {
  // 当前页
  pageNum: number;
  // 每页显示条数
  pageSize: number;
}

// 初始化默认参数
const props = withDefaults(defineProps<IProps>(), {
  loading: false,
  rowKey: "id",
  dynamic: 0,
  showEditBtn: true,
  highlightCurrentRow: false,
  showSelection: false,
  showDeleteBtn: true,
  deleteHasPerm: [],
  editHasPerm: [],
  shoeOperations: true,
  operationsWidth: 150,
  operationsAlign: "center",
  operationsHeaderAlign: "center",
  expandRowKeys: [],
});

// 插槽对象
const slots = useSlots();

// 定义组件发出的事件
const emit = defineEmits([
  "handleEdit",
  "handleDelete",
  "handlePagination",
  "handleSelectionChange",
  "handlePage",
]);

const tableHeight = ref<any>();

// watch监听动态计算table的高度,根据dynamic是否大于0,dynamic层级大于height
watch(
  [() => props.height, () => props.dynamic],
  ([height, dynamic]) => {
    if (height && !dynamic) {
      tableHeight.value = height;
    } else if ((!height && dynamic) || (height && dynamic)) {
      // 获取浏览器窗口高度
      const windowHeight = window.innerHeight;
      tableHeight.value = windowHeight - dynamic;
    } else {
      tableHeight.value = "auto";
    }
  },
  {
    deep: true,
    immediate: true,
  }
);

// 增加样式Class
const tableRowClassName = ({
  row,
  rowIndex,
}: {
  row: Object;
  rowIndex: number;
}) => {
  if (rowIndex % 2 === 1) {
    return "warning-row";
  }
  return "";
};

// 点了多选
const handleSelectionChange = (val: ITableModel[]) => {
  emit("handleSelectionChange", val);
};

// 点击了编辑
const handleEdit = (data: object, index: number) => {
  emit("handleEdit", data, index);
};

// 点击了删除
const handleDelete = (data: object, index: number) => {
  emit("handleDelete", data, index);
};
</script>

使用案例

<Table
        :dynamic="dynamicHeight"
        :tableModels="table.tableModels"
        :data="table.data"
        :loading="table.loading"
        :showSelection="table.showSelection"
        :operationsWidth="table.operationsWidth"
        @handle-edit="openDialog"
        @handle-delete="handleDelete"
        @handle-selection-change="handleSelectionChange"
      >
        <!-- 自定义列【status】字段 -->
        <template #status="scope">
          <el-tag size="small" v-if="scope.status === 1" type="success">
            正常
          </el-tag>
          <el-tag size="small" v-else type="info">禁用</el-tag>
        </template>
        <!-- 操作栏从开头增加按钮 -->
        <template #operationsStart="scope">
          <el-button
            type="primary"
            size="small"
            link
            :icon="Position"
            @click="openMenuDialog(scope)"
          >
            分配权限
          </el-button>
        </template>
      </Table>

渲染表格的数据

const table = reactive({
  tableModels: [
    {
      label: "角色名称",
      key: "name",
      align: "left",
      headerAlign: "center",
      value: "name",
      minWidth: 200,
    },
    {
      label: "角色编码",
      key: "code",
      width: 200,
      align: "center",
      headerAlign: "center",
      value: "code",
    },
    {
      label: "数据权限",
      key: "dataScope",
      width: 200,
      align: "center",
      headerAlign: "center",
      value: "dataScope",
    },
    {
      label: "状态",
      key: "status",
      width: 200,
      align: "center",
      headerAlign: "center",
      value: "status",
    },
    {
      label: "排序",
      key: "sort",
      width: 200,
      align: "center",
      headerAlign: "center",
      value: "sort",
    },
  ],
  data: [] as any[],
  showSelection: true,
  operationsWidth: 250,
  loading: false,
});

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins自动化搭建记录

每一份努力都是有一份期盼&#xff0c;每一份付出都是为了有更多的收获。 本文记录一次搭建Jenkins自动参数化打包APK的实现过程和碰到的问题&#xff0c;实现了在Windows和Mac系统下的自动化打包流程。 因为Jenkins的安装过程在网上的教程很多&#xff0c;这里就不在赘述。 …

使用 LlamaIndex 和 Llama 2-Chat 构建知识驱动的对话应用程序

文章目录 使用 LlamaIndex 和 Llama 2-Chat 构建知识驱动的对话应用程序Llama 2-70B-聊天LlamaIndex 解决方案概述先决条件使用 SageMaker JumpStart 部署 GPT-J 嵌入模型使用 SageMaker Python SDK 进行部署在 SageMaker Studio 中使用 SageMaker JumpStart 进行部署使用 Sage…

Dashboard 介绍

Dashboard 介绍 一、K8S Dashboard简介 简单的说&#xff0c;K8S Dashboard是官方的一个基于WEB的用户界面&#xff0c;专门用来管理K8S集群&#xff0c;并可展示集群的状态。K8S集群安装好后默认没有包含Dashboard&#xff0c;我们需要额外创建它 二、RABC简介 还是那句话&a…

关于下载上传的sheetjs

一、背景 需要讲后端返回来的表格数据通过前端设置导出其中某些字段&#xff0c;而且得是xlsx格式的。 那就考虑使用控件SheetJS。如果是几年前&#xff0c;一般来说&#xff0c;保存excel的文件都是后端去处理&#xff0c;处理完成给前端一个接口&#xff0c;前端调用了打开…

SQLite的扩展函数Carray()表值函数(三十八)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite如何处理CSV 虚拟表 下一篇&#xff1a;SQLite—系列文章目录 ​ 1. 概述 Carray()是一个具有单列的表值函数(名为 “value”)和零行或多行。 carray() 中每一行的“值”取自 C 语言数组 由应用程序通过参数绑定提…

如何进行面向对象分析、面向对象设计和面向对象编程

目录 1.引言 2.案例介绍和难点剖析 3.如何进行面向对象分析 4.如何进行面向对象设计 5.如何进行面向对象编程 6.总结 1.引言 面向对象分析(OOA)、面向对象设计(00D)和面向对象编程(OOP)是面向对象开发的3个主要环节。 在以往的工作中&#xff0c;作者发现&#xff0c;很多…

JavaScript原型链深度剖析

目录 前言 一、原型链 1.原型链的主要组成 原型&#xff08;Prototype&#xff09; 构造函数&#xff08;Constructor&#xff09; 实例&#xff08;Instance&#xff09; 2.原型链的工作原理 前言 在JavaScript的世界中&#xff0c;原型链&#xff08;Prototype Chain&…

Amazon云计算AWS之[4]非关系型数据库服务SimpleDB和DynamoDB

文章目录 简介非关系型VS关系数据库SimpleDB域条目属性值SimpleDB的使用 DynamoDBSimpleDB VS DynamoDB 简介 非关系型数据库服务主要用于存储结构化的数据&#xff0c;并为这些数据提供查找、删除等基本的数据库功能。AWS中提供的非关系型数据库主要包括SimpleDB和DynamoDB …

聚醚醚酮(Polyether Ether Ketone)PEEK在粘接使用时可以使用UV胶水吗?要注意哪些事项?

一般情况下&#xff0c;聚醚醚酮&#xff08;Polyether Ether Ketone&#xff0c;PEEK&#xff09;是一种难以黏附的高性能工程塑料&#xff0c;而UV胶水通常不是与PEEK进行粘接的首选方法。PEEK表面的化学性质和高温性能使得它对常规胶水的附着性较低。然而&#xff0c;有一些…

(成品论文22页)24深圳杯数学建模A题1-4问完整代码+参考论文重磅更新!!!!

论文如下&#xff1a; 基于三球定位的多个火箭残骸的准确定位 针对问题一&#xff1a;为了进行单个残骸的精确定位&#xff0c;确定单个火箭残骸发生音爆 时的精确位置和时间&#xff0c;本文基于三球定位模型&#xff0c;考虑到解的存在性和唯一性&#xff0c; 选取了四个监测…

用HTML5实现播放gif文件

用HTML5实现播放gif文件 在HTML5中&#xff0c;你可以使用<img>标签来播放GIF文件。GIF文件本质上是一种图像格式&#xff0c;它支持动画效果&#xff0c;因此当在网页上加载时&#xff0c;它会自动播放动画。先看一个简单的示例&#xff1a; <!DOCTYPE html> &l…

清华同方电脑文件删除怎么恢复

在日常使用清华同方电脑的过程中&#xff0c;我们难免会遇到误删重要文件的情况。文件丢失不仅可能导致数据损失&#xff0c;还可能影响到我们的工作、学习甚至是生活。那么&#xff0c;当在清华同方电脑上删除了重要文件后&#xff0c;我们应该如何恢复呢&#xff1f;本文将为…

Linux服务器安全基础 - 查看入侵痕迹

1. 常见系统日志 /var/log/cron 记录了系统定时任务相关的日志 /var/log/dmesg 记录了系统在开机时内核自检的信息&#xff0c;也可以使用dmesg命令直接查看内核自检信息 /var/log/secure:记录登录系统存取数据的文件;例如:pop3,ssh,telnet,ftp等都会记录在此. /var/log/btmp:记…

服务器被攻击,为什么后台任务管理器无法打开?

在服务器遭受DDoS攻击后&#xff0c;当后台任务管理器由于系统资源耗尽无法打开时&#xff0c;管理员需要依赖间接手段来进行攻击类型的判断和解决措施的实施。由于涉及真实代码可能涉及到敏感操作&#xff0c;这里将以概念性伪代码和示例指令的方式来说明。 判断攻击类型 步…

C#---使用Coravel实现定时任务

Coravel是一款框架轻&#xff0c;使用简单&#xff0c;支持秒级定时任务。 1.添加NuGet引用 2.定义自己的工作任务 using Coravel.Invocable; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Thread…

【Java笔记】JVM:对象在内存中是什么样的?如何计算对象占用的内存大小?

文章目录 Java对象的内存布局计算对象占用的内存大小Openjdk jol来算几个Object o new Object() 该对象在内存中占用多少字节&#xff1f;基本数据类型作为成员变量的对象有实例对象作为成员变量的对象 Java对象的内存布局 Java中&#xff0c;一个实例对象在内存中的组成主要包…

国家开放大学2024年春《Matlab语言及其应用》实验五Simulink系统 建模与仿真参考答案

答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 实验报告 姓名&#xff1a; 学号&#xff1a; 实验五名称…

【JAVA进阶篇教学】第九篇:MyBatis-Plus用法介绍

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第九篇&#xff1a;MyBatis-Plus用法介绍。 在 MyBatis-Plus 3.5.0 中&#xff0c;LambdaQueryWrapper支持多种条件构造方式&#xff0c;除了等于&#xff08;eq&#xff09;、不等于&#xff08;ne&#xff09;、大于&a…

大模型公开课-大模型的语言解码游戏学习总结

在当今快速发展的人工智能领域&#xff0c;深度学习作为其中的一项关键技术&#xff0c;正引领着科技的新潮流。而对于初学者来说&#xff0c;了解大型语言模型的解码游戏&#xff0c;对于理解深度学习的基本概念至关重要。本篇博客将对一次关于大型语言模型解码游戏的视频教学…

SQL如何利用Bitmap思想优化array_contains()函数

目录 0 问题描述 1 位图思想 2 案例实战 3 小结 0 问题描述 在工作中&#xff0c;我们往往使用array_contains()函数来进行存在性问题分析&#xff0c;如判断某个数是否在某个数组中&#xff0c;但是当表数据量过多&#xff0c;存在大量array_contains()函数时&#xff0c;…
最新文章