应无所住,而生其心
排名
1
文章
858
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

ElementUI Table 动态表头,动态数据,动态列

3974人阅读 2024/5/13 11:50 总访问:5169670 评论:0 收藏:0 手机
分类: 前端

表格显示的列不确定的时候就需要使用动态的方式,而不是预先绑定好。

前端的实现

数据源

对于前端来说数据源和前面的一样,没什么区别,反正就是提供一下数据

  1. const data = [
  2. {
  3. name: 'John Doe',
  4. age: 30,
  5. city: 'New York'
  6. },
  7. {
  8. name: 'Jane Smith',
  9. age: 25,
  10. city: 'London'
  11. },
  12. {
  13. name: 'Michael Jones',
  14. age: 40,
  15. city: 'Paris'
  16. }
  17. ];

动态表头

表头就不能写死了,需要绑定的来,相当于列就是动态的显示的,不是预先绑定好的

  1. const columns = [
  2. {
  3. prop: 'name',
  4. label: '姓名'
  5. },
  6. {
  7. prop: 'age',
  8. label: '年龄'
  9. },
  10. {
  11. prop: 'city',
  12. label: '城市'
  13. }
  14. ];

然后这样绑定上去就可以动态的渲染出来表头了

  1. <el-table :data="data" :columns="columns"></el-table>

上面那个不好写一些额外的列,比如还有一些固定的列和编辑列这种,所以可以把需要动态显示的列循环出来

  1. <el-table :data="state.tableData" v-loading="state.tableLoading"
  2. :header-cell-style="{ background: '#f8f8f9' }" style="width: 100%;margin-top:-10px">
  3. <el-table-column prop="className" label="班级" show-overflow-tooltip min-width="219" />
  4. <el-table-column prop="studentCount" sortable label="学生数" align="center" min-width="119" />
  5. <!-- 循环出来需要动态显示的列 -->
  6. <el-table-column :label="item.label" min-width="139" :prop="item.prop" v-bind:key="index" v-for="(item, index) in state.dynamicColumns">
  7. </el-table-column>
  8. <el-table-column header-align="center" align="center" label="操作" width="90px" fixed="right">
  9. <template #default="scope">
  10. <el-link :underline="false" @click="showDetails(scope.row)" type="primary">详情</el-link>
  11. </template>
  12. </el-table-column>
  13. </el-table>

后端的实现

需要提供动态的数据源和动态的表头,c# 可以使用ExpandoObject 构建动态类型

后台需要的相关实体

动态表头需要的实体

  1. public class ElementTableColumn
  2. {
  3. public string prop { get; set; }
  4. public string label { get; set; }
  5. }

接口需要返回的实体

  1. public class ElementTableDynamic
  2. {
  3. /// <summary>
  4. /// 动态表头
  5. /// </summary>
  6. public List<ElementTableColumn> Columns { get; set; }
  7. /// <summary>
  8. /// 动态数据
  9. /// </summary>
  10. public List<ExpandoObject> Data { get; set; }
  11. }

动态构建数据的逻辑

这里主要贴的是动态构建数据的逻辑,具体的业务逻辑需要换成自己的

  1. public ElementTableDynamic ClassMonthTaskReport(ClassStatisticsParams _params)
  2. {
  3. // 这里边是需要显示动态数据的
  4. List<Tasks> tasks = BaseDal.Db.Queryable<Tasks>().OrderBy(a => a.OrderNum).OrderBy(a => a.CreateTime).Take(_params.TakeCount).ToList();
  5. // 其他逻辑.....
  6. // 构建动态的表头
  7. List<ElementTableColumn> elementTableColumns = new List<ElementTableColumn>();
  8. foreach (Tasks taskItem in tasks)
  9. {
  10. ElementTableColumn elementTableColumn = new ElementTableColumn();
  11. // elementTableColumn.label = taskItem.TaskName;
  12. // 列名显示这个短名称吧
  13. elementTableColumn.label = taskItem.ReportName;
  14. // 动态列名,用id来拼一个名称,显示的可能会随时调整(当然也可以在数据库单独创建一列来存储一个列名,反正列都是动态的一般来说都没必要)
  15. elementTableColumn.prop = "completeShow" + taskItem.ID;
  16. elementTableColumns.Add(elementTableColumn);
  17. }
  18. List<ExpandoObject> expandoObjectList = new List<ExpandoObject>();
  19. // 构建动态数据
  20. foreach (VClassTeam item in vClassTeams)
  21. {
  22. //创建动态类型。表格这些需要动态显示
  23. dynamic expandoObjectItem = new ExpandoObject();
  24. // 转化成键值对方便动态赋值,这样给键值对赋值就会自动给expandoObjectItem赋值
  25. var expandoDict = (IDictionary<string, object>)expandoObjectItem;
  26. // 固定列的数据
  27. expandoDict["levelID"] = item.LevelID;
  28. expandoDict["gradeID"] = item.GradeID;
  29. expandoDict["classId"] = item.ID;
  30. expandoDict["className"] = item.ClassName;
  31. expandoDict["studentCount"] = studentClassList.Count(a => a.ClassID == item.ID);
  32. // 动态数据赋值
  33. foreach (Tasks taskItem in tasks)
  34. {
  35. List<StuTaskDetail> stuTaskDetail_Item = stuTaskDetails.Where(a => a.ClassId == item.ID && a.TaskID == taskItem.ID).ToList();
  36. // 给需要动态显示的列提供值(具体提供值的算法根据自己的业务逻辑来)
  37. expandoDict["completeShow" + taskItem.ID] = stuTaskDetail_Item.GroupBy(a => a.ClassId).Count() + "/" + stuTaskDetail_Item.Count();
  38. }
  39. expandoObjectList.Add(expandoObjectItem);
  40. }
  41. ElementTableDynamic elementTableDynamic = new ElementTableDynamic();
  42. elementTableDynamic.Columns = elementTableColumns;
  43. elementTableDynamic.Data = expandoObjectList;
  44. return elementTableDynamic;
  45. }

接口返回的数据格式如下

前端需要复杂一些的模板解析

当数据不是简单的直接绑定一个列的时候,比如需要点击查询详情等,还需要提供详情的数据

比如前端需要这样绑定数据

  1. <el-table-column prop="managerOfficeMeetingCount" align="center" label="总经办会议" min-width="109">
  2. <template #default="scope">
  3. <span class="canclick"
  4. @click="showMonthDetails(scope.row.managerOfficeMeetingDetails, '总经办会议', scope.row.managerOfficeMeetingCount)">{{
  5. scope.row.managerOfficeMeetingShow }}</span>
  6. </template>
  7. </el-table-column>

后端

这样后端就还需要多提供几个数据,详情数据:managerOfficeMeetingDetails,条数:managerOfficeMeetingCount 等,后台大概的核心代码如下:

  1. // 动态数据赋值
  2. foreach (Tasks taskItem in tasks)
  3. {
  4. List<StuTaskDetail> stuTaskDetail_Item = stuTaskDetails.Where(a => a.ClassId == item.ID && a.TaskID == taskItem.ID).ToList();
  5. // 给需要动态显示的列提供值(具体提供值的算法根据自己的业务逻辑来)
  6. expandoDict["completeShow" + taskItem.ID] = stuTaskDetail_Item.GroupBy(a => a.ClassId).Count() + "/" + stuTaskDetail_Item.Count();
  7. expandoDict["completeCount" + taskItem.ID] = groupTasks_Item.GroupBy(a => a.ClassID).Count();
  8. expandoDict["completeDetails" + taskItem.ID] = ProcGroupTasksDetails(item, schoolClassDtos, groupTasks_Item);
  9. }

动态构建表头的时候就在加一个字段,方便前端解析的时候去取对应的数据

  1. // 构建动态的表头与属性对应的数据
  2. List<ElementTableColumn> elementTableColumns = new List<ElementTableColumn>();
  3. foreach (Tasks taskItem in tasks)
  4. {
  5. ElementTableColumn elementTableColumn = new ElementTableColumn();
  6. elementTableColumn.label = taskItem.ReportName;
  7. elementTableColumn.prop = "completeShow" + taskItem.ID;
  8. // 多加一个字段,方便前端解析的时候去取
  9. elementTableColumn.taskId = taskItem.ID+"";
  10. elementTableColumns.Add(elementTableColumn);
  11. }
这样修改后,后端返回的数据结构如下:

表头的数据结构:

具体数据的结构:

前端

这种情况下详情数据前端解析的时候也要动态的来了,不能写死,要根据那个动态id来拼接出来取数据

  1. <!-- 循环出来需要动态显示的列 -->
  2. <el-table-column :label="item.label" min-width="139" align="center" :prop="item.prop" v-bind:key="index"
  3. v-for="(item, index) in state.dynamicColumns">
  4. <template #default="scope">
  5. <span class="canclick"
  6. @click="showMonthDetails(scope.row['completeDetails'+item.taskId], item.label,scope.row['completeCount'+item.taskId])">{{
  7. scope.row[item.prop]
  8. }}</span>
  9. </template>
  10. </el-table-column>

需要多级表头,合并表头的

效果如下:

element ui的多级表头格式如下,相当于就是有嵌套效果的
  1. <el-table-column label="地址">
  2. <el-table-column
  3. prop="province"
  4. label="省份"
  5. width="120">
  6. </el-table-column>
  7. <el-table-column
  8. prop="city"
  9. label="市区"
  10. width="120">
  11. </el-table-column>
  12. </el-table-column>
后台表头的结构就需要变一下了,需要有一个子级
  1. public class ElementTableColumn
  2. {
  3. public string prop { get; set; }
  4. public string label { get; set; }
  5. public string taskId { get; set; }
  6. /// <summary>
  7. /// 可能有多级表头的情况
  8. /// </summary>
  9. public List<ElementTableColumn> subTableColumn { get; set; }
  10. }
需要有子级的情况,后台构建的时候就要多添加一级
  1. // 构建动态的表头与属性对应的数据
  2. List<ElementTableColumn> elementTableColumns = new List<ElementTableColumn>();
  3. foreach (Tasks taskItem in tasks)
  4. {
  5. // 班级数量和具体的完成数量还要合并成一个单元来显示
  6. ElementTableColumn elementTableColumnFather = new ElementTableColumn();
  7. elementTableColumnFather.label = taskItem.ReportName;
  8. List<ElementTableColumn> subTableColumn = new List<ElementTableColumn>();
  9. // 2024-5-29,说某个任务完成的班级数量单独作为一列显示出来,那么在加一列吧,放到那个显示的数据列前面
  10. ElementTableColumn classCompleteCountTableColumn = new ElementTableColumn();
  11. classCompleteCountTableColumn.label = "班级数";
  12. classCompleteCountTableColumn.prop = "classCompleteCount" + taskItem.ID;
  13. classCompleteCountTableColumn.taskId = taskItem.ID + "";
  14. subTableColumn.Add(classCompleteCountTableColumn);
  15. ElementTableColumn elementTableColumn = new ElementTableColumn();
  16. elementTableColumn.label = "完成次数";
  17. // 动态列名,用id来拼一个名称,显示的可能会随时调整
  18. elementTableColumn.prop = "completeShow" + taskItem.ID;
  19. elementTableColumn.taskId = taskItem.ID + "";
  20. subTableColumn.Add(elementTableColumn);
  21. elementTableColumnFather.subTableColumn = subTableColumn;
  22. elementTableColumns.Add(elementTableColumnFather);
  23. }
前台解析的时候多加一级循环即可
  1. <!-- 循环出来需要动态显示的列,需要合并一级的单元格 -->
  2. <el-table-column :label="fatheritem.label" align="center" v-for="(fatheritem, index) in state.dynamicColumns" :key="index">
  3. <el-table-column :label="item.label" min-width="139" align="center" :prop="item.prop"
  4. v-bind:key="index" v-for="(item, index) in fatheritem.subTableColumn">
  5. <template #default="scope">
  6. <span class="canclick"
  7. @click="showMonthDetails(scope.row['completeDetails' + item.taskId], item.label, scope.row['completeCount' + item.taskId])">{{
  8. scope.row[item.prop]
  9. }}</span>
  10. </template>
  11. </el-table-column>
  12. </el-table-column>
动态表头返回的数据结构的一部分如下


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

vue-ElementUI Table loading效果加载效果

官方文档:https://element.eleme.cn/#/zh-CN/component/loadingElement 提供了两种调用 Loading 的方法:指令和服务。对于...

vue ElementUI Table去掉滚动条

当table内容列过多时,可通过height属性设置table高度以固定table高度、固定表头,使table内容可以滚动。现在需求是右侧滚...

css弹性盒子flex布局

css弹性盒子由于版本不同浏览器问题造成了一些不同的写法display:flexbox;在google浏览器中如果使用下面的写法就不行displa...

可输入下拉文本框据输入动态加载数据 jquery-editable-select

用到一个jquery-editable-select的控件github地址:https://github.com/indrimuska/jquery-editable-select这个插件的原理是...

.net mvc分部页.net core分部页

.net分部页的三种方式第一种:@Html.Partial(&quot;_分部页&quot;)第二种:@{ Html.RenderPartial(&quot;分部页&quot;);}...

css中单位pxemrem和vh/vw的理解

&gt;px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。em是相对长度单位。相对于当前对象内文本的字...

让IIS支持webp格式图片让IIS支持vtt格式iis设置mime类型iis配置支持的类型

webp格式图片可以让图片体积变小。也让下载图片变得更加困难一点 在线制作webp工具 https://www.upyun.com/webp?utm_mediu...

网页上传文件断点续传的实现无视文件大小上传以及datatables基本用法

首先明白js是客户带执行代码,c#是服务器上执行代码。本地文件需要用到js处理,服务器端接受c#代码处理1.HTML页面,文件信...

如何使用图标像使用文字一样使用文本图标的方法

1.首先在Iconfont-阿里巴巴矢量图标库上面找到你需要的图标然后加入你的购物车然后选择图标;注意:每个类型的图标会大小不...

使用七牛云的cdn服务提高图片的加载速度

CDN介绍CDN的全称是Content Delivery Network,即内容分发网络。CDN加速主要是加速静态资源,如网站上面上传的图片、媒体,...

通俗易懂什么是.NET?什么是.NET Framework?什么是.NET Core?

朋友圈@蓝羽 看到一篇文章写的太详细太通俗了,搬过来细细看完,保证你对.NET有个新的认识理解原文地址:https://www.cnblo...

JS监听input、keydown有输入法时打字完成后触发事件

在给输入框绑定input或keydown事件时预期效果是有输入法时,输入中文后触发事件,不希望输一个字母就触发一次事件可以用到c...

修改了css后让浏览器从缓存中更新

当我们修改了css后,如果不做一些操作,浏览器是不会自动更新我们的样式文件的。除非是过期或者用户手动刷新清理缓存等。所...

C MVC RedirectToAction跳转时候传递参数Action之间传值

MVC Action之间传值,页面跳转传值方法一:路由传值很简单直接使用 RedirectToAction(string actionName, string controller...