el |
您所在的位置:网站首页 › 表头合并单元格 › el |
先看效果图:
最近要用Vue+ElementUI实现这种表格样式,因为也是第一次对el-table做这种处理,所以并不知晓是不是有更优的解决方案。把自己的代码放上来,欢迎大家提供更简单的实现方法哈。 PS: 红框内容:表头嵌套,通过el-table-column嵌套即可实现; 蓝框内容:左侧为表头跨列;右侧为表头跨行。(右侧效果:如果用el-table-column嵌套,会造成"考试结果"占一行,"成绩"占两行。) 我的方案有些繁琐,先通过header-cell-class-name设置class名,然后在mounted里通过原生Js获取到dom节点,setAttribute实现; 黄框内容:凡是相邻的单元格,如果是同一所学校的话,就自动合并。最关键就是要获取到要合并的行数,详见代码。
let me; export default { data() { return { tableData: [ { schoolName: 'A小学', studentNo: '2018001', studentName: 'Jack', studentScore: 92, testLevel: '优秀', studentAge: 17 }, { schoolName: 'A小学', studentNo: '2018002', studentName: 'Lily', studentScore: 99, testLevel: '优秀', studentAge: 16 }, { schoolName: 'A小学', studentNo: '2018003', studentName: 'Sony', studentScore: 58, testLevel: '不及格', studentAge: 18 }, { schoolName: 'B小学', studentNo: '2018004', studentName: 'Tom', studentScore: 74, testLevel: '良好', studentAge: 16 }, { schoolName: 'B小学', studentNo: '2018005', studentName: 'Jackie', studentScore: 92, testLevel: '优秀', studentAge: 16 }, { schoolName: 'B小学', studentNo: '2018006', studentName: 'Joe', studentScore: 99, testLevel: '优秀', studentAge: 16 }, { schoolName: 'B小学', studentNo: '2018007', studentName: 'Kobe', studentScore: 58, testLevel: '不及格', studentAge: 17 }, { schoolName: 'C小学', studentNo: '2018008', studentName: 'Tomcat', studentScore: 74, testLevel: '良好', studentAge: 17 }, { schoolName: 'B小学', studentNo: '2018009', studentName: 'Trump', studentScore: 92, testLevel: '优秀', studentAge: 18 }, { schoolName: 'C小学', studentNo: '2018010', studentName: 'Lily', studentScore: 49, testLevel: '不及格', studentAge: 17 }, { schoolName: 'C小学', studentNo: '2018011', studentName: 'Sony', studentScore: 58, testLevel: '不及格', studentAge: 17 }, { schoolName: 'C小学', studentNo: '2018012', studentName: 'Tom', studentScore: 74, testLevel: '良好', studentAge: 17 }, { schoolName: 'C小学', studentNo: '2018013', studentName: 'Jack', studentScore: 52, testLevel: '不及格', studentAge: 17 }, { schoolName: 'C小学', studentNo: '2018014', studentName: 'Lily', studentScore: 99, testLevel: '优秀', studentAge: 17 }, ] } }, mounted(){ me = this; var timer = setInterval(()=>{ console.log('计时器10ms执行一次,一旦找到目标节点即停止') var setCrossRowDom1 = document.getElementsByClassName('setCrossRow1'); var setCrossRowDom2 = document.getElementsByClassName('setCrossRow2'); var setCrossColDom1 = document.getElementsByClassName('setCrossCol1'); var setCrossColDom2 = document.getElementsByClassName('setCrossCol2'); if(setCrossRowDom1.length > 0 && setCrossRowDom2.length > 0 && setCrossColDom1.length > 0 && setCrossColDom2.length > 0){ setCrossRowDom1[0].setAttribute('rowspan', 2) setCrossRowDom2[0].setAttribute('style', 'display: none;') setCrossColDom1[0].setAttribute('colspan', 2) setCrossColDom2[0].setAttribute('style', 'display: none;') clearInterval(timer); timer = null; } }, 10) }, methods: { // 一加载就给表头设置class,通过js设置表头里的单元格合并 headerCrossRow({rowIndex, column}){ if(rowIndex === 1 && column.label === '考试结果'){ return 'setCrossRow1'; } else if (rowIndex === 2 && !column.label) { return 'setCrossRow2'; } else if (column.label === '标识') { return 'setCrossCol1'; } else if (column.label === '学号') { return 'setCrossCol2'; } }, moreRowsToOneRow({ rowIndex, columnIndex }){ // 学校是不同学生可能共同拥有的属性,所以需要合并。 // 其他属性不应该合并,比如成绩,即使成绩相等,也不应该合并为同一个单元格 if (columnIndex === 2) { // 遍历各行 看是要合并行、合并几行,还是隐藏 // 比如第7行开始要合并3行,那么第8行和第9行就得隐藏,要不然会右移占用其他单元格 for (var i of Array.from(me.tableData.keys())) { if(rowIndex === i){ return me.heBingRowOfColumn2(i)//计算{colspan: X, rowspan: Y}的值 } } } }, heBingRowOfColumn2(i){ var itemList = me.tableData.map(item=>{ return item.schoolName }) // 先拿到学校列表,本示例中拿到的数组为: // ["A小学", "A小学", "A小学", "B小学", "B小学", "B小学", "B小学", "C小学", "B小学", "C小学", "C小学", "C小学", "C小学", "C小学"] // 第一行,没有上一行,所以要单独处理下 var returnObj = null; if(i == 0){ console.log(`${itemList[i]}从下标${i}开始出现了${countShowTimes(itemList, i)}次`) returnObj = { colspan: 1, rowspan: countShowTimes(itemList, i) } } else if (i >= 1) {// 第二行开始: if(itemList[i] == itemList[i-1]){// 如果和上面一行值相等,就隐藏 returnObj = { colspan: 0, rowspan: 0 } } else {// 如果和上面一行值不相等 console.log(`${itemList[i]}从第${i}开始出现了${countShowTimes(itemList, i)}次`) returnObj = { colspan: 1, rowspan: countShowTimes(itemList, i) } } } return returnObj;//把合并的列数 行数返回给span-method的方法 // 计算连续出现的次数,然后合并 // 一旦有不同的值,则需要重新计数 function countShowTimes (itemList, i) { var count = 1; // 如果一进来就是最后一个元素,那肯定只能出现一次,直接return if(i == (itemList.length-1)){ return 1; } for (var n=i+1;n |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |