
在日常开发中我们常遇到这样的需求将一张常规表格行记录列字段转置展示即把原表的列名变为行数据原表的每一行数据变为新表的一列。这种“行列反转”在统计报表、数据对比、参数配置等场景中非常实用。vxe-table 本身不提供内置的转置功能但借助其灵活的 columns 和 data 配置我们可以通过简单的数据转换轻松实现。本文将详细拆解实现逻辑并提供可复用的代码模板。需求场景与效果预览假设原表格结构如下横向展示多条记录的多个字段IDNameRoleSexAgeAddress10001Test1DevelopMan28Shenzhen10002Test2TestWomen22Beijing………………转置后我们希望得到这样的表格字段名记录1记录2记录3…ID100011000210003…NameTest1Test2Test3…RoleDevelopTestPM…SexManWomenMan…Age282232…AddressShenzhenBeijingShanghai…即原字段作为行原每条记录作为列形成类似“数据透视”的展示方式。核心实现思路vxe-grid 的数据由 columns列定义和 data数据行决定。要实现转置我们需要新表头columns原数据的每一条记录对应新表的一列col1, col2, …并增加一个固定列用于显示原字段名。新数据data原表的每个字段field对应新表的一行该行的各列值即为原数据中各记录的对应字段值。因此转换逻辑本质上是二维数组的转置操作只是我们保留原字段名作为第一列的值。分步实现详解准备原始数据定义原始列配置 myColumns包含所有字段和原始数据 myData多条记录constmyColumns[{field:id,title:ID},{field:name,title:Name},// ... 更多字段]constmyData[{id:10001,name:Test1,...},{id:10002,name:Test2,...},// ... 更多记录]编写转换函数 reverseTable该函数负责构建新表格的 columns 和 dataconstreverseTable(){// 1. 构建新数据每个原字段对应一行行内各列为原各条记录的值constbuildDatamyColumns.map((column){constitem{col0:column.title}// 第一列存放字段名原titlemyData.forEach((row,index){item[col${index1}]row[column.field]// 动态列名 col1, col2, ...})returnitem})// 2. 构建新列定义第一列固定显示字段名其余列对应原各条记录constbuildColumns[{field:col0,fixed:left,width:100}// 固定左侧便于浏览]myData.forEach((_,index){buildColumns.push({field:col${index1},minWidth:200// 可根据内容调整})})// 3. 赋值给 gridOptionsgridOptions.databuildData gridOptions.columnsbuildColumns}关键点说明col0 固定列用于展示原字段名使用 fixed: ‘left’ 使其在水平滚动时保持可见。动态列名 col1, col2, … 对应原数据中的第1条、第2条记录顺序与原数组索引一致。minWidth: 200 保证内容较长的字段如 Address能完整展示也可根据需要设为固定 width。样式微调可选为了让转置后的表格更易读通常将第一列字段名列赋予特殊背景色突出其“标签”属性.reverse-table .vxe-body--row .vxe-body--column:first-child{background-color:#f8f8f9;}代码templatedivvxe-gridclassreverse-tablev-bindgridOptions/vxe-grid/div/templatescriptsetupimport{reactive}fromvueconstgridOptionsreactive({border:true,showOverflow:true,height:400,showHeader:false,columns:[],data:[]})constmyColumns[{field:id,title:ID},{field:name,title:Name},{field:role,title:Role},{field:sex,title:Sex},{field:age,title:Age},{field:address,title:Address},{field:rate,title:Rate},{field:date3,title:Date},{field:updateTime,title:UpdateTime},{field:createTime,title:CreateTime}]constmyData[{id:10001,name:Test1,nickname:T1,role:Develop,sex:Man,age:28,rate:2,address:Shenzhen,date3:20:30,updateTime:2020-09-16,createTime:2020-09-16},{id:10002,name:Test2,nickname:T2,role:Test,sex:Women,age:22,rate:2,address:Beijin,date3:20:30,updateTime:2019-09-16,createTime:2020-09-16},{id:10003,name:Test3,nickname:T3,role:PM,sex:Man,age:32,rate:6,address:Shanghai,date3:20:30,updateTime:2020-09-16,createTime:2021-09-16},{id:10004,name:Test4,nickname:T4,role:Designer,sex:Women,age:23,rate:2,address:Shenzhen,date3:20:30,updateTime:2020-09-16,createTime:2020-09-16},{id:10005,name:Test5,nickname:T5,role:Develop,sex:Women,age:30,rate:10,address:Shanghai Beijin Shenzhen Shenzhen Guangzhou,date3:20:30,updateTime:2020-01-16,createTime:2020-10-16},{id:10006,name:Test6,nickname:T6,role:Designer,sex:Women,age:21,rate:2,address:Shenzhen,date3:20:30,updateTime:2018-09-16,createTime:2020-09-16},{id:10007,name:Test7,nickname:T7,role:Test,sex:Man,age:29,rate:3,address:Shenzhen,date3:20:30,updateTime:2020-01-16,createTime:2020-10-16},{id:10008,name:Test8,nickname:T8,role:Develop,sex:Man,age:35,rate:2,address:Beijin Beijin Beijin,date3:20:30,updateTime:2017-09-16,createTime:2020-09-16},{id:10009,name:Test9,nickname:T9,role:Test,sex:Man,age:29,rate:3,address:Shenzhen,date3:20:30,updateTime:2020-01-16,createTime:2020-10-16},{id:10010,name:Test10,nickname:T10,role:Develop,sex:Man,age:50,rate:5,address:Shenzhen,date3:20:30,updateTime:2017-09-16,createTime:2020-09-16}]constreverseTable(){constbuildDatamyColumns.map((column){constitem{col0:column.title}myData.forEach((row,index){item[col${index1}]row[column.field]})returnitem})constbuildColumns[{field:col0,fixed:left,width:100}]myData.forEach((item,index){buildColumns.push({field:col${index1},minWidth:200})})gridOptions.databuildData gridOptions.columnsbuildColumns}reverseTable()/scriptstylelangscss.reverse-table .vxe-body--row .vxe-body--column:first-child{background-color:#f8f8f9;}/style注意事项与优化建议数据量限制转置后列数 原记录数行数 原字段数。若原记录过多如超过 50 条新表会有大量列水平滚动体验变差。建议对记录数进行分页或限制展示条数。字段值为对象或复杂类型若原字段值为对象、数组等直接赋值会显示 [object Object]。请在转换时进行格式化例如调用 JSON.stringify 或提取特定属性。缺失值处理若原记录中某些字段不存在row[column.field] 会返回 undefined单元格将显示空。可根据需要设置默认值如 ‘—’。表头与列名示例中设置 showHeader: false因为第一行字段名已承担表头角色。若需显示列标题如“记录1”、“记录2”可保留 showHeader: true并在 buildColumns 中设置 title 属性。固定列与滚动将第一列固定fixed: ‘left’有助于用户在横向滚动时始终看到字段名称提升可读性。动态更新若原始数据变化需重新调用 reverseTable 更新 gridOptions。可将其封装为方法并在数据变更时触发。通过简单的数据映射我们利用 vxe-table 的基础能力实现了行列反转功能。代码清晰、无侵入且保留了组件原有的排序、筛选、导出等扩展能力。该方法适用于字段数量有限、记录数量适中的场景是数据透视展示的一种轻量级替代方案。若需更复杂的多维分析可考虑集成专业的透视表库但对于大多数管理后台需求本方案已足够。https://vxetable.cn