当前位置: 首页 > 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.cnnetsun.cn/news/1970273.html

相关文章:

  • 黎阳之光核工厂202应急管控平台|全域实景孪生,筑牢核安全最后一道防线
  • MT7916芯片深度解析:从拆机中兴E1630看MTK首款AX3000方案
  • LaTeX 数学排版进阶:从特殊字体到复杂公式布局
  • 3大核心功能深度解析:揭秘Waifu2x-Extension-GUI如何让模糊图片视频瞬间高清
  • 为什么这3款降AI率工具能霸榜排行榜?深度解读背后原因
  • 终于搞懂了:降AI率工具排行榜的排名逻辑是什么
  • SQLAlchemy 2.1 系列第二个测试版发布,新增 mssql-python DBAPI 支持
  • tts-vue:5分钟搭建专业级本地语音合成系统的完整指南
  • 跨平台输入法词库转换终极指南:如何用imewlconverter打破设备壁垒?
  • FanControl完全指南:5分钟掌握Windows风扇精准控制,告别电脑噪音烦恼
  • Rockchip RK3588 kernel dts解析之电源管理实战:从关机充电到电量计配置
  • 做 GEO 之前要准备哪些资料:基础信息、内容素材与信号资产清单
  • 从库仑到高斯:解锁电磁学核心定律的工程应用视角
  • 工创赛智能物流搬运小车——V831视觉循迹与STM32色环校准完整方案
  • Nginx如何配置phpMyAdmin访问_反向代理设置方法
  • CFCA精品可可饮品师初级认证课程重塑:告别粉冲思维,确立液态环境下的严密判断顺序
  • 深度学习 | Detectron2实战:从零构建自定义检测模型
  • 山东大学软件学院2026项目实训个人博客(二)
  • 合并报表系统:多公司财务报表的自动合并
  • 43453453
  • SOCD Cleaner终极指南:如何用键盘映射提升游戏操作精度
  • 结合上篇文“怪奇物语物流假设”的对死亡搁浅3的构想
  • Keil C51和MDK共存安装后,别忘了这几步:芯片包离线安装、许可证管理及环境变量配置(附资源包)
  • 软件建造者管理化的复杂对象构建
  • 如何将本地文件夹的数据全量同步到MongoDB GridFS
  • 手把手教你用PyTorch从零搭建并调优MobileNetV3图像分类模型
  • 微动弹性带方法实战:从能量地形到过渡态精准定位
  • 怎么监控MongoDB副本集的复制缓冲区积压_复制流速率评估
  • 别再死记硬背了!用PyTorch/TensorFlow代码实战,带你搞懂Sigmoid到GELU六大激活函数的‘脾气’
  • Novel-Downloader:200+小说网站一键下载的终极解决方案,告别404烦恼!