深入理解element-plus table二次封装:从理论到实践的全面指南

前言

在许多中后台管理系统中,表格占据着半壁江山,如果使用element plus组件库,那么少不了要用到table组件,可是table组件的功能过于基础,因此,我在table组件的实现基础之上进一步封装,从而实现功能更强大的table组件。

在实现table组件的功能之前,我们首先需要先来看看用法,由于使用示例比较多,可能将会有几篇文章主要介绍所有示例用法,介绍完示例之后将会有专门的文章基于使用方式去详细讲解封装思路。

毕竟我们要实现一个东西,就应该需要先理解这个东西怎么用的,从如何使用再去推导如何实现就会很有思路了。

所以在实现之前,我们需要先来具体了解一下每个示例的用法和效果。

首先这个组件被我封装成以插件的形式来使用,我们可以看到在main.ts下的使用代码如下所示:

import { createApp } from 'vue'
import App from './App.vue'
//...
import ElementTable from './components/index'


const app = createApp(App);
//....
app.use(ElementTable);
app.mount('#app')

如此一来,我们就可以全局使用该组件了。

示例1-基础使用

组件支持传入column和data属性,即表格列数据和表体数据,前面我们已经说过了,我们是在全局当中注册好了,因此在vue文件当中可以直接使用。示例代码如下:

 <element-table :column="column" :data="tableData" />

然后就是ts代码,如下所示:

import { ElTableColumnProps } from '../components/tableProps';
/* 引入ElTableColumnProps定义column可获得类型提示 */
const column: ElTableColumnProps[] = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
// 后续如无特殊说明,表体数据都是这个
const tableData = [
  {
    date: "2016-05-02",
    name: "佘太君",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-04",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1517 弄",
  },
  {
    date: "2016-05-01",
    name: "王小帅",
    address: "上海市普陀区金沙江路 1519 弄",
  },
  {
    date: "2016-05-03",
    name: "王小呆",
    address: "上海市普陀区金沙江路 1516 弄",
  },
];

从这个示例,我们可以看到,我们的column传入一个对象数组,对象的属性包含prop,label,type,width等属性,其中type值为index,代表制定一个索引列,然后label和prop分别指定列名以及对应绑定的表体数据字段名,width则指定列宽。

上述代码展示效果如下所示:

在这里插入图片描述

示例2–基础的render table

render渲染函数html部分和前面示例1保持一致,唯一不同的是ts代码,我们只需要绑定column和data属性数据即可,一个示例代码如下所示:

import { h } from 'vue';
// 这里是导入的类型
import { ElTableColumnProps } from '../components/tableProps';
const column: ElTableColumnProps[] = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    label: "名字",
    prop: "name",
    render: (data, scope) => {
      const { row, column } = scope;
      const propKey = column.property;
      return h('div', null, { default: () => `render 结果 -- ${row[propKey]}== ${data}` })
    },
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];

上述代码展示效果如下所示:

在这里插入图片描述

从这个示例,我们可以看到,render是一个渲染函数,代表自定义渲染列。

这里尤其需要注意render函数的参数,第一个参数指的是数据,第二个参数则指的是当前表格上下文,我们可以从中获取一些属性,例如列数据column,行数据row等等,从而实现自定义渲染表体。

示例3–插槽用法

关于使用插槽,我们通常使用一个template标签,并制定#加属性值来表示,如示例:

 <element-table :column="column" :data="tableData">
    <template #name="{ row }">
      <div>
        <span>
          <code>name</code>
          插槽--{{ row.name }}
        </span>
      </div>
    </template>
    <template #default>
      <div>
        <span>
          默认插槽名字为
          <strong>default</strong>
        </span>
      </div>
    </template>
  </element-table>

这里分成了两种插槽,第一种是具名插槽,通过#[属性名(这里的属性名通过column里的slotName属性指定)]指定,第二种则是默认插槽,通过#default(与前面具名插槽原理类似)指定,然后在配置的column列数据中,我们通过slotName来指定插槽名,代码如下所示:

const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    label: "具名插槽",
    slotName: "name",
  },
  {
    label: "默认插槽",
    slotName: "default",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];

上述代码展示效果如下所示:

在这里插入图片描述

示例4–边框

边框table,只是在组件当中传入一个border属性即可,其它跟前面示例没什么两样。代码如下所示:

<element-table border :column="column" :data="tableData" />

ts代码忽略,以上代码展示效果如下图所示:

在这里插入图片描述

示例5–自定义列渲染

在前面的示例3当中,我们已经初窥自定义列渲染的实现了,接下来这个示例,我们将基于示例3,实现更为复杂的自定义渲染列示例。我们将会引入element-plus的icon(图标)组件和popover(悬浮对话框)组件。代码如下所示:

  <element-table :column="column" :data="tableData" style="width: 100%">
    <template #date="scope">
      <div style="display: flex; align-items: center">
        <el-icon>
          <timer />
        </el-icon>
        <span style="margin-left: 10px">{{ scope.row.date }}</span>
      </div>
    </template>
    <template #name="scope">
      <el-popover effect="light" trigger="hover" placement="top" width="auto">
        <template #default>
          <div>name: {{ scope.row.name }}</div>
          <div>address: {{ scope.row.address }}</div>
        </template>
        <template #reference>
          <el-tag>{{ scope.row.name }}</el-tag>
        </template>
      </el-popover>
    </template>
    <template #default="scope">
      <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
        >Edit</el-button
      >
      <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"
        >Delete</el-button
      >
    </template>
  </element-table>

接下来,来看我们的ts代码,如下所示:

import { Timer } from "@element-plus/icons-vue";

interface User {
  date: string;
  name: string;
  address: string;
}

const handleEdit = (index: number, row: User) => {
  console.log(index, row);
};
const handleDelete = (index: number, row: User) => {
  console.log(index, row);
};

const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "date",
    label: "日期",
    width: 180,
    slotName: "date",
  },
  {
    prop: "name",
    width: 180,
    label: "名字",
    slotName: "name",
  },
  {
    prop: "address",
    label: "Operations",
    slotName: "default",
  },
];

const tableData: User[] = [
  //...
];

这个示例其实也还是插槽的用法,只不过多了绑定按钮事件。上述代码展示效果如下所示:

在这里插入图片描述

示例6-自定义表头

自定义表头与自定义列渲染是同一个原理,也是插槽用法,只不过自定义列的插槽名属性叫做slotName,而自定义表头的插槽名则叫做headerSlot,然后就可以像自定义列那样自定义表头即可。如以下一个示例:

 <element-table :column="column" :data="filterTableData" style="width: 100%">
    <template #header>
      <el-input v-model="search" size="small" placeholder="Type to search" />
    </template>
    <template #default="scope">
      <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
        >Edit</el-button
      >
      <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"
        >Delete</el-button
      >
    </template>
  </element-table>

然后我们的ts代码就可以基于搜索框,实现数据的过滤,利用ref函数创建一个响应式数据,也就是search。代码如下所示:

import { ref, computed } from "vue";

interface User {
  date: string;
  name: string;
  address: string;
}

const search = ref("");
//...注意这里
const filterTableData = computed(() =>
  tableData.filter(
    (data) =>
      !search.value || data.name.toLowerCase().includes(search.value.toLowerCase())
  )
);

const handleEdit = (index: number, row: User) => {
  console.log(index, row);
};
const handleDelete = (index: number, row: User) => {
  console.log(index, row);
};

const column = [
  {
    prop: "date",
    label: "日期",
    width: 180,
    slotName: "date",
  },
  {
    prop: "name",
    width: 180,
    label: "名字",
    slotName: "name",
  },
  {
    align: "right",
    slotName: "default",
    //这里就是自定义表头的自定义插槽名
    headerSlot: "header",
  },
];

const tableData: User[] = [
  //...
];

以上代码展示效果如下图所示:

在这里插入图片描述

输入搜索值之后,展示效果如下图所示:

在这里插入图片描述

示例7–自定义索引值

自定义索引值示例很简单,只需要配置列的index属性值为一个函数即可,代码如下:

const indexMethod = (index: number) => index * 2;
const column = [
  {
    type: "index",
    //主要是这里
    index: indexMethod,
  },
 //...
];
const tableData = [
    // ...
]

其余的没什么变化,html代码也很简单,如下所示:

<element-table :column="column" :data="tableData" style="width: 100%"></element-table>

以上代码展示效果如下图所示:

在这里插入图片描述

项目附件:点此下载

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

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

相关文章

Windows直接运行python程序

Windows直接运行python程序 一、新建bat脚本二、新建vbs脚本 一、新建bat脚本 新建bat批处理脚本&#xff0c;写入以下内容 echo off call conda activate pytorch python app.pyecho off&#xff1a;在此语句后所有运行的命令都不显示命令行本身&#xff0c;但是本身的指令是…

微信小程序的页面交互练习——实现比较两数大小功能

前提&#xff1a;配置好页面后 一、在wxml里面搭建好框架&#xff1a; <navigation-bar title"Weixin" back"{{false}}" color"black" background"#FFF"></navigation-bar> <scroll-view class"scrollarea"…

简单了解原型模式

什么是原型模式 区别于单例模式&#xff0c;原型模式的一个类可以有多个实例化的对象。 原型模式通过拷贝来产生新的对象&#xff0c;而不是new&#xff0c;并且可以根据自己的需求修改对象的属性。 实现Cloneable接口实现拷贝 而拷贝又分为浅拷贝和深拷贝&#xff0c;两者在…

大模型论文阅读:ADAPTIVE BUDGET ALLOCATION FOR PARAMETEREFFICIENT FINE-TUNING

大模型论文阅读:ADAPTIVE BUDGET ALLOCATION FOR PARAMETEREFFICIENT FINE-TUNING 论文链接:https://arxiv.org/pdf/2303.10512v1.pdf 当存在大量下游任务时,微调所有预训练模型的参数变得不可行。因此,为了以参数高效的方式学习预训练权重的增量更新,提出了许多微调方法,…

node.js项目初始化操作

项目环境Vscode 1.新建一个文件夹node.js(xx.js) 2.右键点击node.js&#xff0c;点击打开终端 我在VScode打开终端 输入npm init初始化项目没反应。 解决方法&#xff1a;进入文件夹node.js&#xff0c;出入cmd跳转到终端 重新输入npm init命令 正确结果如下图 后续命令按下…

酷开科技依托酷开系统用“平台+产品+场景”塑造全屋智能生活!

杰弗里摩尔的“鸿沟理论”中写道&#xff1a;高科技企业推进产品的早期市场和产品被广泛接受的主流市场之间&#xff0c;存在着一条巨大的“鸿沟”。“鸿沟”&#xff0c;指产品吸引早期接纳者后、赢得更多客户前的那段间歇&#xff0c;以及其中可预知和不可预知的阻碍。多数产…

SPRING-BOOT实现HTTP大文件断点续传分片下载

版本&#xff1a;6.5.40 代码&#xff1a;up6-jsp-springboot: Web大文件上传-jsp-springboot示例 - Gitee.com nosql示例 nosql示例不需要进行任何配置&#xff0c;可以直接访问测试。 SQL示例 1.创建数据库 2.配置数据库连接 3.自动下载maven依赖 4.启动项目 启动成功 6.访…

Oracle VM(虚拟机)性能监控工具

Oracle VM是一个独立的虚拟化环境&#xff0c;由 Oracle 提供支持和设计&#xff0c;旨在为运行虚拟机提供轻量级、安全的基于服务器的平台。Oracle VM 能够在受支持的虚拟化环境中部署操作系统和应用软件&#xff0c;Oracle VM 将用户和管理员与底层虚拟化技术隔离开来&#x…

队列+宽搜例题讲解!

429. N 叉树的层序遍历 题目解析&#xff1a; 根据题目分析&#xff0c;可以看出题目要我们求的是N叉数的层序遍历&#xff0c;就是把每层的放在一块&#xff0c;最后把每层都输出出来即可&#xff01; 算法分析&#xff1a; 我们可以利用队列先进先出的特性进行求解&#x…

56. 合并区间(力扣LeetCode)

文章目录 56. 合并区间题目描述思路贪心算法方法一&#xff1a;直接在res中修改代码逻辑梳理&#xff1a; 方法二&#xff1a;在原数组中插入一个超出题目范围的数组代码逻辑梳理&#xff1a; 56. 合并区间 题目描述 以数组 intervals 表示若干个区间的集合&#xff0c;其中单…

MyBatis-Plus分页接口实现教程:Spring Boot中如何编写分页查询

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

http响应练习—在服务器端渲染html(SSR)

一、什么是服务器端渲染&#xff08;SSR&#xff09; 简单说&#xff0c;就是在服务器上把网页生成好&#xff0c;整个的HTML页面生成出来&#xff0c;生成出的页面已经包含了所有必要的数据和结构信息&#xff0c;然后直接发给浏览器进行展现。 二、例题 要求搭建http服务&a…

白板手推公式性质 AR模型 时间序列分析

白板手推公式性质 AR模型 时间序列分析 视频讲解&#xff1a;https://www.bilibili.com/video/BV1D1421S76v/?spm_id_from.dynamic.content.click&vd_source6e452cd7908a2d9b382932f345476fd1 B站对应视频讲解(白板手推公式性质 AR模型 时间序列分析)

Java 学习和实践笔记(49):用javabean和一维数组的方式来存储表格数据

还是存储下面这个表格的数据&#xff0c;但使用另一种方法来做。 用javabean和一维数组的方法来做&#xff0c;示例代码如下&#xff1a; /*先创建一个类&#xff0c;其实就是创建好一个只有各属性列的空表格*/ class Employees {private int id;private String name;private …

【Linux进阶之路】理解UDP,成为TCP。

前言 学了TCP 和UDP之后&#xff0c;感觉UDP就像是初入职场的年轻人&#xff0c;两耳不闻 “窗外事”&#xff0c;只管尽力地把自己的事情做好&#xff0c;但收获的却是不可靠&#xff0c;而TCP更像是涉世极深的"职场老油条"&#xff0c;给人的感觉就是 “城府极深&a…

H12-831_338

多选题338、某园区部署OSPF实现网络互通&#xff0c;其中R2的LSDB如图所示。以下关于该LSDB信息的描述&#xff0c;错误的有哪些项? A.此时R4不能访间地址10.1.35.5/24&#xff0c;因为R4所在的Area l内没有泛洪R3-R5互联网段路由信息 B.Area l内无3类LSA&#xff0c;有7类1SA…

【jenkins+cmake+svn管理c++项目】jenkins回传文件到svn(windows)

书接上文&#xff1a;创建一个项目 在经过cmakemsbuild顺利生成动态库之后&#xff0c;考虑到我一个项目可能会生成多个动态库&#xff0c;它们分散在build内的不同文件夹&#xff0c;我希望能将它们收拢到一个文件夹下&#xff0c;并将其回传到svn。 一、动态库移位—cmake实…

C# wpf 嵌入wpf控件

WPF Hwnd窗口互操作系列 第一章 嵌入Hwnd窗口 第二章 嵌入WinForm控件 第三章 嵌入WPF控件&#xff08;本章&#xff09; 文章目录 WPF Hwnd窗口互操作系列前言一、如何实现&#xff1f;1、继承HwndHost2、添加Content属性3、创建wpf窗口并设置Content4、关闭wpf窗口 二、完整…

Flutter 常用插件Plugin整理并附带实例

最近有点空闲时间&#xff0c;正好写一篇文章&#xff0c;整理一下我们在Flutter开发中常用的插件Plugin使用并附带上实例。 在日常开发中&#xff0c;整个demo目前应该满足大家所有的开发需求&#xff0c;例如&#xff1a;http请求、列表刷新及加载、列表分组、轮播图、视频播…

ASP.Net添加Swagger注释

文章目录 Swagger添加Swagger注释 Swagger 添加Swagger注释 1、右击项目->选择属性->点击生成->输出&#xff0c;选中文档文件 2、配置服务 在program.cs 文件里配置SwaggerUI //增加项一 builder.Services.AddSwaggerGen(c> {c.SwaggerDoc("v1", ne…