当前位置: 首页 > news >正文

vue2+element-UI表格封装

针对表格进行封装,在列表页面直接传入字段数组就可以展示数据表:

<template><divclass="table-container":class="{ 'show-vertical-lines': showVerticalLines }"><!--数据表格--><el-table ref="tableRef":data="tableData"border size="mini"style="width: 100%":max-height="tableHeight"row-key="id":row-class-name="rowClassName"highlight-current-row><!--单选框列--><el-table-column v-if="showRadio"width="55"align="center"><template slot-scope="scope"><el-radio v-model="radioSelection":label="scope.row.id"@change="handleRadioChange(scope.row)">&nbsp;</el-radio></template></el-table-column><!--多选框列--><el-table-column v-if="showSelection"type="selection"width="55"align="center"></el-table-column><!--序号列--><el-table-column v-if="showIndex"type="index"label="序号"width="60"align="center"><template slot-scope="scope">{{scope.$index+1}}</template></el-table-column><!--动态列--><el-table-column v-for="(column, index) in columns":key="column.prop || index":prop="column.prop":label="column.label":width="column.width":min-width="column.minWidth || 80":header-align="column.headerAlign || 'left'":align="column.align || 'left'":fixed="column.fixed"><template slot-scope="scope"><!--作用域插槽:允许父组件自定义内容--><slot:name="column.prop":row="scope.row":editable="isRowEditable(scope.row)"><!--默认渲染逻辑--><template v-if="isRowEditable(scope.row) && column.editable === true"><el-input v-model="scope.row[column.prop]"size="small"@blur="handleInputBlur(scope.row, column.prop)"@click.native.stop></el-input></template><template v-else><!--超长文本省略--><el-tooltip v-if="scope.row[column.prop] && scope.row[column.prop].toString().length > 100":content="scope.row[column.prop]"placement="top"effect="dark"><divclass="ellipsis-text">{{scope.row[column.prop]}}</div></el-tooltip><span v-else>{{scope.row[column.prop]}}</span></template></slot></template></el-table-column></el-table><!--分页--><divclass="pagination-fixed"><el-pagination @size-change="$emit('size-change', $event)"@current-change="$emit('current-change', $event)":current-page="currentPage":page-sizes="[10, 20, 50, 100]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"background style="text-align:right;"></el-pagination></div></div></template><script>exportdefault{name:"TableContainer",props:{tableData:{type:Array,default:()=>[]},columns:{type:Array,default:()=>[]},currentPage:{type:Number,default:1},pageSize:{type:Number,default:10},total:{type:Number,default:0},showSelection:{type:Boolean,default:false},showRadio:{type:Boolean,default:false},showIndex:{type:Boolean,default:false},showVerticalLines:{type:Boolean,default:false},// 新增:允许父组件传入表格距离顶部的偏移量,默认 260pxoffsetTop:{type:Number,default:260}},data(){return{radioSelection:null,tempBackup:null,// 新增:用于存储当前正在编辑行的快照tableHeight:400};},mounted(){this.$nextTick(()=>{this.calculateTableHeight();});window.addEventListener('resize',this.calculateTableHeight);},beforeDestroy(){window.removeEventListener('resize',this.calculateTableHeight);},methods:{rowClassName({row}){returnthis.radioSelection===row.id?'radio-selected':'';},isRowEditable(row){returnthis.radioSelection===row.id;},// 核心逻辑:处理单选框切换handleRadioChange(currentRow){// 1. 恢复上一行的数据 (如果存在上一行且备份存在)if(this.tempBackup){// 找到表格数据中对应的那一行对象constprevRowData=this.tableData.find(item=>item.id===this.tempBackup.id);if(prevRowData){// 用备份的数据覆盖当前表格中的数据(撤销修改)Object.assign(prevRowData,JSON.parse(JSON.stringify(this.tempBackup)));}}// 2. 为当前点击的这一行创建新的备份// 注意:这里必须深拷贝,否则 tempBackup 会跟着表格数据一起变this.tempBackup=JSON.parse(JSON.stringify(currentRow));// 3. 触发外部事件this.$emit('radio-change',currentRow);},handleInputBlur(row,prop){this.$emit('input-blur',row,prop);},calculateTableHeight(){// 方式一:基于窗口高度减去固定偏移量(简单粗暴)// this.tableHeight = window.innerHeight - this.offsetTop;// 方式二:更精准的计算(推荐)// 获取表格容器相对于视口的位置constrect=this.$el.getBoundingClientRect();// 视口高度 - 表格顶部距离 - 分页高度(约50) - 底部留白(20)this.tableHeight=window.innerHeight-rect.top-70;// 设置最小高度防止过小if(this.tableHeight<200)this.tableHeight=200;}},emits:['size-change','current-change','radio-change','input-blur']};</script><style scoped>.table-container{width:100%;position:relative;background-color:#fff;/* border-radius: 4px; *//* box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); */overflow:hidden;}.el-table{width:100%;margin:0;}/* 核心调整:行高缩小至 24px,与文字大小一致 */.el-table__row{height:24px!important;}.el-table__cell{padding:012px;/* 上下padding设为0,仅保留左右 */line-height:1.2;vertical-align:middle;/* 确保垂直居中 */}/* 确保表头高度也同步缩小 */::v-deep.el-table th{height:24px!important;line-height:24px!important;background-color:#f0f2f5!important;font-weight:600!important;user-select:text!important;}/* 消除单元格底部多余边框间距 */::v-deep.el-table--border::after,::v-deep.el-table--group::after,::v-deep.el-table::before{height:0;}.pagination-fixed{margin-top:0;display:flex;justify-content:flex-end;align-items:center;padding:6px0;background-color:#fff;}.banner-image{max-width:100px;max-height:50px;}.radio-selected{background-color:#f0f9eb!important;}.ellipsis-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%;display:inline-block;}/* 隐藏表格竖线 */.table-container:not(.show-vertical-lines)::v-deep.el-table th,.table-container:not(.show-vertical-lines)::v-deep.el-table td{border-right:none!important;border-left:none!important;}.table-container:not(.show-vertical-lines)::v-deep.el-table--border,.table-container:not(.show-vertical-lines)::v-deep.el-table--group{border-right:none!important;border-left:none!important;}</style>

传入字段数组格式:

data(){return{tableData:[],columns:[{prop:'title',label:'标题',minWidth:80},{prop:'introduction',label:'内容简介',minWidth:200},{prop:'publishTime',label:'发布时间',minWidth:80},{prop:'status',label:'状态',minWidth:50},{prop:'createTime',label:'创建时间',minWidth:80},{prop:'createBy',label:'创建人',minWidth:80},{prop:'action',label:'操作',minWidth:80,headerAlign:'center',align:'center'}],currentPage:1,pageSize:10,total:0,};},

调用方式:

<table-container:table-data="tableData":columns="columns":current-page="currentPage":page-size="pageSize":total="total":base-url="baseUrl":show-selection="false":show-index="true"@size-change="handleSizeChange"@current-change="handleCurrentChange"><template #status="{ row }"><span v-if="row.status === 1"style="color:#13ce66">已发布</span><span v-elsestyle="color:#ff4949">未发布</span></template><template #createBy="{ row }"><span v-if="row.createBy">{{getCreateUser(row)}}</span></template><template #action="{ row }"><el-button v-if="row.status === 0"type="text"@click="handleEdit(row)">编辑</el-button><span v-if="row.status === 0"style="margin:0 8px;color:#ddd">|</span><el-button v-if="row.status === 0"type="text"@click="handlePublish(row)">发布</el-button><span v-if="row.status === 0"style="margin:0 8px;color:#ddd">|</span><el-button v-if="row.status !== 0"type="text"@click="handlePreview(row)">预览</el-button><span v-if="row.status !== 0"style="margin:0 8px;color:#ddd">|</span><el-button type="text"@click="handleDelete(row.id)">删除</el-button></template></table-container></div>
http://www.jsqmd.com/news/663529/

相关文章:

  • 智能调度赋能交通行业:从经验驱动到数据智能的跨越
  • 跳一跳小游戏辅助工具
  • Leetcode242.『有效的字母异位词』学习笔记
  • 树莓派4B网络启动后,如何用NFS挂载实现多台Pi共享一个系统镜像?
  • 别再手动调学习率了!用Keras的CosineAnnealing回调函数,让你的模型收敛又快又稳
  • OTFS调制解析:从时频域到多普勒-延时域的通信革新
  • Spring Boot 用户注册接口(含事务 + 参数校验)
  • RDKit终极指南:从零开始掌握化学信息学与药物设计
  • STM32实战:DAC电压输出与ADC自校准闭环系统
  • 嘎嘎降AI和PaperRR哪个适合留学论文:Turnitin达标效果对比
  • 为什么92%的AGI系统在监管沙盒中因“解释失败”被一票否决?——基于17个真实审计案例的穿透式复盘
  • 黎阳之光核工厂202应急管控平台|全域实景孪生,筑牢核安全最后一道防线
  • 别再手动算了!用PyTorch Hook一键统计你的CNN模型参数量与FLOPs(附完整代码)
  • 别再只输密码了!手把手带你用Wireshark抓包,亲手‘看见’WPA2的四次握手过程(含过滤技巧)
  • 如何用RL4CO构建智能决策引擎:5分钟掌握强化学习组合优化
  • OP-TEE安全存储深度解析(一):密钥层级与文件加密流程
  • 别再折腾环境了!Win10+GTX1060保姆级YOLOv4训练环境配置(CUDA10.1/CUDNN8.0.3/OpenCV4.4.0)
  • 从零手搓SM3国密算法:用C++一步步实现哈希函数(附完整可运行代码)
  • 解锁MATLAB算力:GPU并行计算实战指南
  • 如何用 filter 过滤数组中不符合业务条件的冗余数据
  • 从CH344Q出发:打造高性能USB转4路TTL串口模块的设计实践
  • 软件测试核心概念实战解析:从理论到习题的深度贯通
  • 别再让VAE学废了!手把手教你诊断和修复‘后验坍塌’(附PyTorch代码)
  • 从滤波到优化:手把手拆解VIO算法核心,看懂OpenVINS的MSCKF和ORB-SLAM3的BA到底差在哪
  • AI代码配额=新型IT预算?2026奇点大会披露:头部企业已将配额消耗纳入DevOps成本中心KPI(含真实财务映射表)
  • 最新 AI 论文盘点(2026-04-12):5 篇新作看长时记忆、推理微调、可审计医疗抽取、端侧个性化与分层 RAG
  • 从IoU到EIoU:目标检测边界框回归损失函数的演进与实战解析
  • 用周立功CAN分析仪抓包解析电动汽车充电握手(附真实报文数据)
  • 从原理到代码:手把手教你用C语言和OpenSSL实现RSA分段加密与验签(附完整项目)
  • ABR 会将自身所在区域内的路由(包括直连网段)通过 Type 3 LSA 通告到其他区域,但不会通告回本区域