vue element-ui el-table表格二次封装 自定义el-table表格组件 vue封装表格组件

article/2025/10/7 6:04:00

CommTable.vue table组件

<template><div><el-table:data="tableData"border:class="tabClass ? tabClass : null":showHeader="showHeader ? showHeader : true":spanMethod="spanMethod ? spanMethod : null"element-loading-text="加载中..."v-loading="loading":height="height ? height : null":maxHeight="maxHeight ? maxHeight : null":ref="tabRef ? tabRef : null":header-cell-style="smallRow ? lineStyle : null":cell-style="smallRow ? lineStyle : null"@sort-change="sortByKey"@selection-change="selectionChange":row-key="rowKey ? rowKey : null"><!-- 详情内容展示 需要showExpand属性  --><el-table-column type="expand" v-if="showExpand"><template slot-scope="{ row }"><slot name="expand" :data="row"></slot></template></el-table-column><!-- checkout复选框  selectionObj对象 {show: true, fixed: true}--><el-table-column type="selection" align="center" width="50" v-if="selectionObj.show" :fixed="selectionObj.fixed ? true : false "></el-table-column><el-table-columnv-for="({ prop, label, width, minWidth ,sortBy, slotName, countLimit, childrenList, className, columnFlag, fixed }, index) in tablecolumn":key="index":prop="prop ? prop : null":label="label ? label : null":width="width ? width : null":min-width="minWidth ? minWidth : 100":sort-by="sortBy ? sortBy : null":sortable="sortBy ? (columnFlag ? 'column' : true) : null":className="className ? className : null":fixed="fixed ? fixed : null":render-header="renderHeader ? renderHeader : null"align="center"><!-- 自定义表头 --><template  slot="header" ><slot v-if="slotName" :name="slotName+'Header'" ></slot></template><!-- 自定义内容 --><template v-if="!childrenList" slot-scope="{row, $index}"><!-- 自定义tamplate --><!-- prop没有值的情况 传整个row --><div  v-if="slotName" ><slot :name="slotName" :data="prop ? row[prop] : null" :index="$index" :rowData="row"></slot></div><!-- 字数(countLimit控制)超出显示tip --><div v-else><div v-if="row[prop] && row[prop].length > (countLimit ? countLimit : 50)"><el-tooltip effect="dark" :content="row[prop]" placement="top" popper-class="tooltipsCont"><span class="limitInfo">{{row[prop] | textSubstr((countLimit ? countLimit : 50))}}</span></el-tooltip></div><div  v-else><span >{{row[prop] | emptyText}}</span></div></div></template><!-- 如果有多组数据 注: 必传prop  childrenList为数据配置项 --><el-table-columnv-if="childrenList && childrenList.length > 0"v-for="(item, index) in childrenList":label="item.label":key="index":width="width ? width : null":min-width="minWidth ? minWidth : 100"align="center"><template slot-scope="{row, $index}"><!-- 自定义tamplate --><div  v-if="slotName"><!-- 插槽传值 data:数组数据 prop:当前数组对象的key index:行索引 --><slot  :name="slotName" :data="prop ? row[prop] : []" :prop="item.prop" :rowData="row" :index="$index"></slot></div><!-- 不是自定义默认遍历数据 row[prop] 获取数组 item.prop为数组配置项的prop --><div v-else ><div class="flex-column"><div v-for="(dataItem, dataIndex) in row[prop]" :key="dataIndex">{{dataItem[item.prop]}}</div></div></div></template></el-table-column></el-table-column></el-table><!-- 分页插槽 --><slot name="el-pagination"></slot></div>
</template>
<script>
import { PropsType } from "../propsType.js";
import Sortable from "sortablejs";
export default {name: "comm_table",data() {return {lineStyle:{'font-size': '14px','height': '45px','padding': '3px 0'},};},props: {tableData: PropsType.Array,tablecolumn: PropsType.Array,loading: PropsType.Boolean,//loadingshowExpand: PropsType.Boolean,//是否展示详情行selectionObj: PropsType.Object,//是否展示详情行height: PropsType.Number,//表格高度maxHeight: PropsType.Number,//表格最大高tabRef:  PropsType.String,//表格refsmallRow: PropsType.Boolean,//控制表格行高showHeader: PropsType.Boolean,//是否显示表头spanMethod: PropsType.Function,//合并行合并列renderHeader: PropsType.Function,//自定义表头tabClass: PropsType.String,//表格class [拖动表格需要的参数]rowKey: PropsType.String,//表格唯一标识 [拖动表格需要的参数]dragTableFlag: PropsType.Boolean,//是否可拖动表格排序 [拖动表格需要的参数]},watch: {},methods: {sortByKey (column) {//排序let params = {}if(column.order){if (column.column) {params.orderBy = column.column.sortByparams.desc = column.column.order === 'descending'params.order = true;}}else{//排序恢复params.order = false;}// else {//自定义初始化排序 看情况传入//例如// params.orderBy = 'avgSales'// params.desc = true// }this.$emit('sortChange', params)},selectionChange(val) {// 表格checkbox 选择行回调this.$emit('selectionChange', val)},rowDrop() {// 此时找到的元素是要拖拽元素的父容器const tbody = document.querySelector(`.${this.tabClass} .el-table__body-wrapper tbody`);const _this = this;Sortable.create(tbody, {// 指定父元素下可被拖拽的子元素draggable: ".el-table__row",onEnd({ newIndex, oldIndex }) {if (newIndex !== oldIndex) {const currRow = _this.tableData.splice(oldIndex, 1)[0];_this.tableData.splice(newIndex, 0, currRow);_this.$emit('getDragTableSort', _this.tableData);}},});},},filters: {textSubstr (value, qtd = 50, mask = '...') {if (!value) return '-';return value.length > qtd ? `${value.substring(0, qtd)}${mask}` : value},emptyText(value){//数据为0的情况显示if(value === ''){return '-'}return value ?? '-'; //或者 (value !== undefined && value !== null) ? vaule : '-'}},mounted() {this.dragTableFlag && this.rowDrop();},
};
</script>
<style lang="scss">
.tooltipsCont{max-width: 500px;max-height: 450px;
}
</style>
<style lang="scss" scoped>
.limitInfo{cursor: pointer;
}
.flex-column{display: flex;flex-direction: column;justify-content: center;align-items: center;
}
</style>

组件中使用的 propsType.js

export const PropsType = {Array: {type: Array,default: ()=>([])},Object: {type: Object,default: ()=>({})},Boolean: {type: Boolean,default: false,},String: {type: String,default: ''},Number: {type: Number,default: 0},Function: Function,Promise: Promise
}

如何使用CommTable组件【基本展示】

<template><div class="content"><div><h1>EC2</h1><CommTabletabRef="ec2Table":tableData="tableData":height="450":tablecolumn="tablecolumn":loading="tableLoading":smallRow="true"@sortChange="getSortParams"><template v-slot:state="{data, index}">{{data ? '显示' : '隐藏'}}</template><template v-slot:desired="{data, index}">{{desiredList.filter(e=>e.value===data)[0].label || '-'}}</template><template v-slot:skuProductList="{data, index, prop}"><!-- prop是属性 data是当前值 --><div class="flex-column"><span v-for="(item, itemIndex) in data" :key="itemIndex">{{item[prop]}}</span></div></template><template v-slot:operate="{rowData, index}"><el-button @click="openEC2Dialog(rowData)" size="mini" type="primary">编辑</el-button></template><el-pagination slot="el-pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="pageNum" :page-sizes="[10, 15, 20, 30, 50]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"></el-pagination></CommTable></div><EC2Dialog :dialogVisible.sync="ec2visible" :rowObj="selectRow"></EC2Dialog></div>
</template>
<script>
import CommTable from "src/components/partials/CommTable.vue";
import EC2Dialog from './components/editEC2Dialog.vue';
export default {name: "operationManagement",components: {CommTable,EC2Dialog},data() {const skuProductColumn = [{prop: 'name', label: 'sku'},{prop: 'count', label: '数量'},{prop: 'price', label: '价格'},];return {tableData: [],tablecolumn: [{ prop: "id", label: "ID" },{ prop: "name", label: "名称" },{ prop: "state", label: "状态" , slotName: 'state'},{ prop: "instances", label: "实用类型" },{ prop: 'skuProductList',label: 'sku信息', slotName: 'skuProductList', minWidth: 200, childrenList: skuProductColumn},{ prop: "privateIPAddres", label: "私有IP地址", sortBy: "privateIPAddres", countLimit: 3, width: 120 },{ prop: "publicIPAddres", label: "公有IP地址" },{ prop: "functionDescription", label: "描述" },{ prop: "desired", label: "预期状态" ,slotName: 'desired'},{ prop: '', label: '操作', slotName: 'operate',}],desiredList: [{ value: 'stop', label: '停止' },{ value: 'delete', label: '删除' },{ value: 'start', label: '启动' },],tableLoading: false,ec2visible: false,pageSize: 15,pageNum: 1,total: 0,selectRow: {}};},methods: {initData() {this.tableLoading = true;setTimeout(() => {this.tableLoading = false;this.tableData = [...Array(10).keys()].map((e) => ({id: e,name: "name" + e,state: false,instances: "实用类型",privateIPAddres: "私有IP地址",publicIPAddres: "公有IP地址",functionDescription: "描述",desired: Math.random() > .5 ? 'stop' : 'delete',skuProductList: [{name: 'H60523D1', count: 2, price: 39.99},{name: 'H60523D2', count: 10, price: 5.99},]}));this.total = 10}, 1000);},openEC2Dialog(row) {this.selectRow = Object.assign({},row);console.log(this.selectRow,'selectRow')this.ec2visible = true;},getSortParams(params) {console.log("sore", params);},handleCurrentChange(val) {this.pageNum = val;this.initData();},handleSizeChange(val) {this.pageSize = val;this.pageNum = 1;this.initData();},},mounted() {this.initData();},
};
</script>
<style lang="scss" scoped>
.content {padding: 20px;
}
.flex-column{display: flex;flex-direction: column;justify-content: center;align-items: center;
}
</style>

**column的配置项介绍 **

{ prop, label, width, minWidth ,sortBy, slotName, countLimit, childrenList, className, columnFlag, fixed }
prop: 字段值
label: 显示名称
…宽度
sortBy: 是排序 当有设置的时候 给定一个字符串 然后 就会通过事件返回这个字符串的排序对象参数
slotName : 是自定义字段 有时候表格内容可能需要改动 添加按钮什么的就需要添加这个
countLimit: 字段展示的字符数
childrenList: 数组数据配置 => [{prop:‘字段值’, label:‘表头’}];
className: 给列名添加类名
columnFlag: 区分前后台排序 默认为前台排序 为true时 后台排序
fixed: 定位

 tablecolumn: [{ prop: "id", label: "ID" },{ prop: "name", label: "名称" },{ prop: "state", label: "状态" , slotName: 'state'},{ prop: "instances", label: "实用类型" },{ prop: 'skuProductList',label: 'sku信息', slotName: 'skuProductList', minWidth: 200, childrenList: skuProductColumn},{ prop: "privateIPAddres", label: "私有IP地址", sortBy: "privateIPAddres", countLimit: 3, width: 120 },{ prop: "publicIPAddres", label: "公有IP地址" },{ prop: "functionDescription", label: "描述" },{ prop: "desired", label: "预期状态" ,slotName: 'desired'},{ prop: '', label: '操作', slotName: 'operate',}],

我调用的时候 有些字段是自定义字段 需要枚举值才可以展示 还有最后的操作按钮

展示一下效果
分页也是可选的 不需要可以不传入插槽就行了
在这里插入图片描述
按钮点击的弹框 事件参数都是可以获取当前表格的值

// 插槽会返回当前插名称 根据插槽名称自定义样式 当前数据 data 如果没有传prop 返回即为空;
当前行数据rowData 和 当前行索引index
//<slot  :name="slotName" :data="prop ? row[prop] : null" :prop="item.prop" :rowData ="row" :index="$index"></slot>
//比如编辑按钮 我们只需要拿到行数据和索引就可以操作你的数据了<template v-slot:operate="{rowData, index}"><el-button @click="openEC2Dialog(rowData)" size="mini" type="primary">编辑					</el-button></template>

在这里插入图片描述

支持自定义表头功能

两种方法
一: 传递renderHeader方法
在这里插入图片描述
methods里添加方法

renderHeader(h, { column }) {switch (column.property) {case 'functionDescription':return [h('span', {}, [column.label+'这是自定义']), h('el-tooltip', { props: { placement: 'top', effect: 'light' } }, [h('div', { slot: 'content' }, [h('p', {}, ['一个提示'])]), h('i', { class: 'helpTips el-icon-info' ,style: 'cursor:pointer;'})])]default:return [h('span', {}, [column.label])]}},

然后查看效果
在这里插入图片描述
二:通过插槽
在这里插入图片描述
这里的是slotName+'Header’的方式 只要定义了slotName然后就可以设置了
在这里插入图片描述
我这里改动的是操作的显示 查看一下效果
在这里插入图片描述
这两种方法都可以改变表头 但是不要一起使用 一起使用会被第一个方法覆盖 插槽就不生效了~

详情内容展示

CommTable组件传入 showExpand true
然后在
在这里插入图片描述
自定义内容就行了

<CommTable:tableData="tableData":maxHeight="350":tablecolumn="tablecolumn":showExpand="true":loading="tableLoading":smallRow="true"><template v-slot:expand="{data}"><span>详情内容{{data}}</span></template><template v-slot:postContent="{data, index}"><div style="max-height: 46px;cursor: pointer;" v-clamp v-html="JSON.parse(data).content"></div></template><template v-slot:operate="{rowData, index}"><el-button @click="openTimeSelDialog(rowData)" size="mini" type="primary">置顶</el-button></template></CommTable>

效果图
在这里插入图片描述

可拖动表格支持

//表格组件使用插件 sortablejs 自行npm下载依赖
import Sortable from "sortablejs";

使用案例

//template
//需要传入的字段: 
// dragTableFlag: 是否可以拖动 默认false 为true的时候需要传入下面的字段
//rowKey:能唯一确定行的key 
//tabClass: 这个需要给定一个值 如果是多个表格都需要拖动要唯一 
//@getDragTableSort: 为拖动后的回调 返回内容为当前表格数据
<CommTable:tableData="tableData":maxHeight="350":tablecolumn="tablecolumn":loading="tableLoading":dragTableFlag="true"@getDragTableSort="getDragTableSort"rowKey="id":tabClass='`detailClass${rowId}`':smallRow="true"></CommTable>//methodsgetDragTableSort(data){console.log(data);//为表格当前排序的值 可以在这里作相应的取值操作或请求}

表格复选框选择 及其定位功能

checkbox 回调函数selectionChange
:selectionObj=“{show: true, fixed: true}” 是否显示行复选框 是否定位

 <CommTable:tableData="tableData":tablecolumn="tablecolumn":selectionObj="{show: true, fixed: true}"ref="tableRef"@selectionChange="selectionChange":loading="loading"></CommTable>  

效果查看
在这里插入图片描述


http://chatgpt.dhexx.cn/article/E4f5H698.shtml

相关文章

Stage的MinWidth和MinHeight的疑问

设置了Stage的MinWidth和MinHeight,但是显示的时候不是这个高度和宽度&#xff0c;最小化之后再次显示的时候就可以了&#xff0c;奇怪 package stage;import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import jav…

php的width是什么意思,minwidth什么意思?min-width怎么设置

很多人刚刚入门css的新手&#xff0c;不知道minwidth什么意思&#xff1f;min-width怎么设置&#xff0c;下面php中文网就带领大家来学习一下min-width。 一&#xff1a;minwidth什么意思 在css中&#xff0c;minwidth是设置段落的最小宽度&#xff0c;使用该属性是设置一个最小…

width和min-width的区别和差异性比较

1、正常情况下&#xff1a; width :给块级元素/行内块 元素设置固定的宽度&#xff0c;或者固定百分比的宽度。 min-width: 当盒子内部元素宽度小于 min-width的值时&#xff0c;盒子宽度为 min-width的值&#xff0c;当盒子内容宽度大于 min-width的值时&#xff0c;盒子随着…

【NOIP2013提高组】华容道

题目背景 NOIP2013 提高组 Day2 试题。 题目描述 小 B 最近迷上了华容道&#xff0c;可是他总是要花很长的时间才能完成一次。于是&#xff0c;他想到用编程来完成华容道&#xff1a;给定一种局面&#xff0c;华容道是否根本就无法完成&#xff0c;如果能完成&#xff0c;最…

【NOIP2013提高组】花匠

题目背景 NOIP2013 提高组 Day2 试题。 题目描述 花匠栋栋种了一排花&#xff0c;每株花都有自己的高度。花儿越长越大&#xff0c;也越来越挤。栋栋决定把这排中的一部分花移走&#xff0c;将剩下的留在原地&#xff0c;使得剩下的花能有空间长大&#xff0c;同时&#xff…

【NOIP2013提高组】积木大赛

题目背景 NOIP2013 提高组 Day2 试题 题目描述 春春幼儿园举办了一年一度的“积木大赛”。今年比赛的内容是搭建一座宽度为 n 的大厦&#xff0c;大厦可以看成由 n 块宽度为 1 的积木组成&#xff0c;第 i 块积木的最终高度需要是 hi。 在搭建开始之前&#xff0c;没有任何…

7.15 NOIP 2013

NOIP 2013 DAY 1 DAY1 T1 转圈游戏 快速幂模板 #include<bits/stdc.h> using namespace std; int n,m,k,x; long long ans; long long cmd(long long a,long long b){long long sum1;for(;a;a>>1){if(a&1){sumsum*b%n;}bb*b%n; } return sum; } int main(…

noip2013 day2

一道纯模拟就可以过&#xff08;水水水&#xff09;。 考试时本蒟蒻甚至写了个线段树&#xff0c;然后发现其实不如直接模拟。 模拟思路&#xff1a; 从1到n枚举每个最长的不为0的序列&#xff0c;每次每个数减去其中剩余的最小值&#xff0c;答案加上这个最小值&#xff0c…

noip2013

D1&#xff1a; T1&#xff1a;快速幂 #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cstdlib> #include<cmath> #define LL long long using namespace std; LL n,m,k,x; inline LL quickpow(LL…

解题报告:NOIP2013 车站分级(拓扑序递推求解差分约束、建图优化O(n+m)) 超详细讲解

本题是2013年NOIP普及组的压轴题 差分约束裸题。 计算当前线路中最小的级别&#xff08;比较始发站和终点站&#xff09;。 整条线路中所有大于这个级别的都必须停靠 所有未停靠的站点的级别一定小于这个级别 也就是说所有未停靠的即为级别低&#xff0c;记为A 所有停靠的站点…

[NOIP2013]记数问题

[NOIP2013]记数问题 1.题目2.分析3.代码方法1&#xff1a;将每个数字的每一位单独算出方法2&#xff1a;转换为字符串再进行遍历 4.反思总结5.更新日志 1.题目 题目链接 题号&#xff1a;NC16538 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C…

ARMv8体系结构基础04:算术和移位指令

目录 1 数据处理指令概述 2 加法指令详解 2.1 ADD指令 2.1.1 ADD&#xff08;extended register&#xff09;指令编码分析 2.1.2 ADD&#xff08;extended register&#xff09;指令编码验证 2.1.3 ADD&#xff08;immediate&#xff09;指令编码分析 2.1.4 ADD&#xf…

8086CPU指令系统--汇编语言逻辑运算和移位操作指令

文章目录 一、逻辑运算指令1、逻辑‘与’指令 AND2、逻辑‘或’指令 OR3、逻辑“非”指令 NOT4、逻辑“异或” XOR5、测试指令TEST 二、移位指令1&#xff09;非循环移位1、算数左移SAL和逻辑左移SHL2、逻辑右移SHR3、算术右移SAR 2&#xff09;循环移位1、带CF的循环左移 RCL2…

arm64汇编学习-(3)算术与移位指令

arm64汇编学习-&#xff08;3&#xff09;算术与移位指令 1 数据处理指令1.1 check the C condition of adds, adc,cmp1.1.1 测试示例程序1.1.2 执行之前1.1.3 执行之后1.1.3.1 ldr和mov指令之后1.1.3.2 ads和adc指令之后1.1.3.3 cmp和adc指令之后 1.2 cmp和sbc指令的综合运用1…

汇编语言——逻辑运算和移位指令

逻辑运算和移位指令 逻辑运算指令 逻辑与AND 格式 AND reg, imm/reg/mem ;reg←reg^imm/reg/mem AND mem, imm/reg ; mem←-mem ^ imm/reg功能:对两个操作数执行按位的逻辑与运算&#xff0c;结果送到目的操作数说明: (1)按位的逻辑与运算; (2)操作数不能同时为存储器操作数…

汇编语言基础之 移位指令

原文: http://bdxnote.blog.163.com/blog/static/ 移位指令是一组经常使用的指令,包括:算数移位、逻辑移位、双精度移位、循环移位、带进位的循环移位; 移位指令都有一个指定需要移动的二进制位数的操作数,该操作数可以是立即数,也可以是CL的值;在8086中,该操作数只能是1,但是在…

x86汇编_移位和循环移位指令简介_笔记46

移位指令与前面介绍的按位操作指令一起形成了汇编语言最显著的特点之一。位移动 (bit shifting) 意味着在操作数内向左或向右移动。x86 处理器在这方面提供了相当丰富的指令集如下表所示&#xff0c;这些指令都会影响溢出标志位和进位标志位。 英文全称汇编指令中文翻译说明意…

PLC移位循环指令

PLC移位循环指令 一、移位指令 移位指令包括无符号数移位和有符号数移位。 其中无符号数移位包含字左移指令、字右移指令、 双字左移指令和双字右移指令&#xff1b;有符号数移位包含整数右移指令和双整数右移指令。 1、无符号数移位指令 &#xff08;1&#xff09;字左移指…

ARM64体系结构编程3-算数和移位指令

条件操作码 条件标志位描述N负数标志&#xff08;上一次运算结果为负值&#xff09;Z零结果标志&#xff08;上一次运算结果为零&#xff09;C进位标志&#xff08;上一次运算结果发生了无符号溢出&#xff09;V溢出标志&#xff08;上一次运算结果发生了有符号溢出&#xff0…

逻辑、移位操作与空指令的实现

逻辑、移位操作和空指令的实现 1. 流水线数据相关的问题 流水线上经常会有一些被称为“相关”的情况发生&#xff0c;它使得指令序列中下一条指令无法按照设计的时钟周期执行&#xff0c;这些“相关”会降低流水线的性能。 1.1 流水线相关 流水线中的相关可分为&#xff1a…