问题形容

本文记录el-table表头合并的多种状况,并提出对应解决方案,预计能帮到局部道友

原生table知识点温习

  • 咱们晓得:一个简略的table表格个别由一个或多个trthtd标签组成(嵌套)
  • tr标签定义表格行(table-row即为tr
  • th标签定义表头(table-header即为th
  • td标签定义表格单元格
再简单的表格还包含 captioncolcolgrouptheadtfoottbody等标签,这里暂不延长

而合并单元格次要应用的是colspanrouspan属性,即为可设置横跨列横跨行的值

而合并单元格次要应用的是colspanrouspan属性,即为可设置横跨列横跨行的值

而合并单元格次要应用的是colspanrouspan属性,即为可设置横跨列横跨行的值

晓得这两个属性当前,咱们联合一个具体demo来看,就很好的了解了

原生表格demo

假如咱们须要做一个周一到周末的表格,记录一下工作内容,如下效果图:

对应代码是这样的:

<table border="1">    <tr>        <th>工作日</th>        <th>工作日</th>        <th>工作日</th>        <th>工作日</th>        <th>工作日</th>        <th>周末</th>        <th>周末</th>    </tr>    <tr>        <th>周一</th>        <th>周二</th>        <th>周三</th>        <th>周四</th>        <th>周五</th>        <th>周六</th>        <th>周日</th>    </tr>    <tr>        <td>下班</td>        <td>下班</td>        <td>下班</td>        <td>下班</td>        <td>下班</td>        <td>加班</td>        <td>加班</td>    </tr></table>

然而,咱们想把五个工作日和两个周末进行合并一下,这样看起来更加优雅一些,如下需要

  • 由图示,咱们晓得第一行的工作日一共有5个,咱们把后4个工作日隐去使其隐没,
  • 让第一个工作日横跨5个单元格宽度,即横跨5列(本来默认都是横跨1列)

先隐去后四个工作日单元格

<tr>    <th>工作日</th>    <th style="display: none;">工作日</th>    <th style="display: none;">工作日</th>    <th style="display: none;">工作日</th>    <th style="display: none;">工作日</th>    <th>周末</th>    <th>周末</th></tr>

变成这样的成果了

  • 这样的话,咱们只须要,再让第一个工作日单元格宽度变宽一些,占据五个单元格,这样的话,宽度有了,就把两个周末挤回到原来失常的地位了
  • 那,如何让第一个工作日单元格,占据五个单元格的宽度呢?
  • 或者说,如何让一个单元格横跨5列?
  • 很简略:<th colspan="5">工作日</th>即可
  • rowspan同理,不赘述

需要实现效果图:

对应需要实现代码:

<table border="1">    <tr>        <th colspan="5">工作日</th>        <th style="display: none;">工作日</th>        <th style="display: none;">工作日</th>        <th style="display: none;">工作日</th>        <th style="display: none;">工作日</th>        <th colspan="2">周末</th>        <th style="display: none;">周末</th>    </tr>    <tr>        <th>周一</th>        <th>周二</th>        <th>周三</th>        <th>周四</th>        <th>周五</th>        <th>周六</th>        <th>周日</th>    </tr>    <tr>        <td>下班</td>        <td>下班</td>        <td>下班</td>        <td>下班</td>        <td>下班</td>        <td>加班</td>        <td>加班</td>    </tr></table>

所以,通过下面的demo,咱们能够得出一个论断:

合并单元格法则论断

  • 合并单元格须要 先暗藏相干单元格,再让某个单元格横向或竖向延长宽度或高度
  • 合并单元格须要 先暗藏相干单元格,再让某个单元格横跨列,或竖跨行

最初咱们审查一下dom元素,发现还真是这样的

el-table单层表头合并案例

无论是饿了么UI还是Iview等相干的UI组件库,都是给原生table套壳子封装的,所以若是须要合并相应单元格,咱们仍旧能够应用上述的思维形式

咱们持续通过案例来看一下,在UI组件库中如何操作合并单元格

本文以表头单元格合并举例,若是有表体单元格合并的需要,能够看笔者之前的这篇文章:https://segmentfault.com/a/1190000040927939

案例一

效果图:

代码:

  • header-cell-style函数用于给表头增加款式,其返回的值会被增加到表头对应款式中去
  • 留神函数的形参中的column.id为单元格的class
  • 大家最好打印一下,联合审查dom看类名
<template>  <el-table    :data="tableData"    border    style="width: 600"    :header-cell-style="headerCellStyle"  >    <el-table-column      prop="name"      label="姓名、年龄、他乡"      width="150"      align="center"    ></el-table-column>    <el-table-column      prop="age"      label="年龄"      width="150"      align="center"    ></el-table-column>    <el-table-column      prop="home"      label="他乡"      width="150"      align="center"    ></el-table-column>    <el-table-column      prop="hobby"      label="喜好"      width="150"      align="center"    ></el-table-column>  </el-table></template><script>export default {  data() {    return {      tableData: [        {          name: "孙悟空",          age: 500,          home: "花果山水帘洞",          hobby: "大闹天宫",        },        {          name: "猪八戒",          age: 88,          home: "高老庄",          hobby: "吃包子",        },        {          name: "沙和尚",          age: 1000,          home: "通天河",          hobby: "游泳",        },        {          name: "唐僧",          age: 99999,          home: "东土大唐",          hobby: "取西经",        },      ],    };  },  methods: {    headerCellStyle({ row, column, rowIndex, columnIndex }) {      // 第一步:设置表头的第0列暂不操作,将地1列和第2列隐去使其隐没      if ((columnIndex == 1) | (columnIndex == 2)) {        return { display: "none" };      }      // 第二步, 因为1、2列没有了,后续列就会贴上来(后续列往左错位问题)      if ((rowIndex == 0) & (columnIndex == 0)) {        // 解决后续列错位问题,就是将隐去的第1、2列的地位再补上,通过第0列来补        this.$nextTick(() => {          // 原来第0列只占据一个地位,当初要去占据三个地位。即占据三列,即设置为横向三个单元格          document.querySelector(`.${column.id}`).setAttribute("colspan", "3");          // 这里的column.id理论是dom元素的class,故用点.不必井#,可审查dom验证          // 通过设置原生的colspan属性,让原来的第一列只占据一个单元格的表头占据3个单元格即可        });      }    },  },};</script><style lang="less">.el-table {  th {    font-weight: bold;    color: #333;  }}</style>

看,基本上一样的用法:先暗藏再设置横跨竖跨单元格

colspan='number' 属性,设置单元格能够横跨几列(默认一个单元格横向只占据一列)

案例二

效果图:

代码:

headerCellStyle({ row, column, rowIndex, columnIndex }) {  // 第一步:隐去第2列单元格  if (columnIndex == 2) {    return { display: "none" };  }  // 第二步,让第1列单元格横跨两列(默认单元格只是横跨一列)  if ((rowIndex == 0) & (columnIndex == 1)) {    this.$nextTick(() => {      document.querySelector(`.${column.id}`).setAttribute("colspan", "2");    });  }},

案例三

效果图:

代码:

headerCellStyle({ row, column, rowIndex, columnIndex }) {  // 第一步:隐去第3列单元格  if (columnIndex == 3) {    return { display: "none" };  }  // 第二步,让第2列单元格横跨两列(默认单元格只是横跨一列)  if ((rowIndex == 0) & (columnIndex == 2)) {    this.$nextTick(() => {      document.querySelector(`.${column.id}`).setAttribute("colspan", "2");    });  }},

案例四

效果图:

代码:

headerCellStyle({ row, column, rowIndex, columnIndex }) {  // 第一步:隐去第1、2、3列单元格  let hideColArr = [1, 2, 3];  if (hideColArr.includes(columnIndex)) {    return { display: "none" };  }  // 第二步,让第0列单元格横跨四列(默认单元格只是横跨一列)  if ((rowIndex == 0) & (columnIndex == 0)) {    this.$nextTick(() => {      document.querySelector(`.${column.id}`).setAttribute("colspan", "4");    });  }},

el-table多级表头合并案例

  • 多级表头,须要进一步通过rowIndex去找到对应的单元格
  • 因为单层表头,表头只有1行,rowIndex必定是0,所以写不写都无所谓
  • 然而多级表头有不少行,所以须要应用 columnIndex,rowIndex 进一步定位单元格
  • 相似于通过X轴 Y轴的坐标定位到某个单元格地位

案例五

效果图:

代码:

html部门须要el-table-column标签进行嵌套

<template>  <el-table    :data="tableData"    border    style="width: 600"    :header-cell-style="headerCellStyle"  >    <el-table-column prop="name" label="姓名" width="150" align="center">      <el-table-column        prop="name"        label="三列根底信息"        width="150"        align="center"      ></el-table-column>    </el-table-column>    <el-table-column prop="name" label="年龄" width="150" align="center">      <el-table-column        prop="age"        label="年龄"        width="150"        align="center"      ></el-table-column>    </el-table-column>    <el-table-column prop="name" label="他乡" width="150" align="center">      <el-table-column        prop="home"        label="他乡"        width="150"        align="center"      ></el-table-column>    </el-table-column>    <el-table-column      prop="hobby"      label="喜好"      width="150"      align="center"    ></el-table-column>  </el-table></template>

js局部持续先暗藏再延长相干单元格

headerCellStyle({ row, column, rowIndex, columnIndex }) {  // 把第1列第1行和第2列第1行的单元格隐去  if ((columnIndex == 1) | (columnIndex == 2)) {    if (rowIndex == 1) { // 加上rowIndex精准定位      return { display: "none" };    }  }  // 而后让第0列第1行的单元格横向占据3个单元格地位填充刚刚隐去导致的空白  if ((columnIndex == 0) & (rowIndex == 1)) { // 加上rowIndex精准定位    this.$nextTick(() => {      document.querySelector(`.${column.id}`).setAttribute("colspan", "3");    });  }},

案例六

效果图:

代码:

仍旧是嵌套

<template>  <el-table    :data="tableData"    border    style="width: 600"    :header-cell-style="headerCellStyle"  >    <el-table-column      prop="name"      label="根本信息(姓名、年龄、他乡)"      align="center"    >    </el-table-column>    <el-table-column      prop="age"      label="年龄"      align="center"    >    </el-table-column>    <el-table-column      prop="home"      label="他乡"      align="center"    >    </el-table-column>    <el-table-column prop="kind" label="所属种族" align="center">    </el-table-column>    <el-table-column label="重要信息" align="center">      <el-table-column label="公开重要信息" align="center">        <el-table-column prop="nickname" label="法号" align="center">        </el-table-column>        <el-table-column prop="hobby" label="喜好&性情" align="center">        </el-table-column>        <el-table-column prop="personality" label="性情" align="center">        </el-table-column>      </el-table-column>      <el-table-column label="窃密重要信息" align="center">        <el-table-column prop="bornBackground" label="出身背景" align="center">        </el-table-column>        <el-table-column prop="skill" label="技能" align="center">        </el-table-column>      </el-table-column>    </el-table-column>  </el-table></template><style lang="less">.el-table {  th {    font-weight: bold;    color: #333;  }}</style>

先找到dom,再操作dom

<script>export default {  data() {    return {      tableData: [        {          name: "孙悟空",          age: 500,          home: "花果山水帘洞",          kind: "monkey",          nickname: "斗战败佛",          hobby: "大闹天宫",          personality: "怯懦坚韧、疾恶如仇",          bornBackground: "仙石孕育而生",          skill: "72变、筋斗云",        },        {          name: "猪八戒",          age: 88,          home: "高老庄",          kind: "pig",          nickname: "净坛使者",          hobby: "吃包子",          personality: "好逸恶劳、贪图女色",          bornBackground: "天蓬元帅错投猪胎",          skill: "36变",        },        {          name: "沙和尚",          age: 1000,          home: "通天河",          kind: "human",          nickname: "金身罗汉",          hobby: "游泳",          personality: "憨厚老实、不辞辛苦",          bornBackground: "卷帘大将被贬下界",          skill: "18变",        },        {          name: "唐僧",          age: 99999,          home: "东土大唐",          kind: "human",          nickname: "檀功德佛",          hobby: "取西经",          personality: "谦恭儒雅、愚善执著",          bornBackground: "金蝉子转世",          skill: "念紧箍咒",        },      ],    };  },  methods: {    headerCellStyle({ row, column, rowIndex, columnIndex }) {      /**       * 合并:根本信息(姓名、年龄、他乡)单元格【通过行与列的索引来合并】       * */      let colArr = [1, 2];      if (colArr.includes(columnIndex)) {        if (rowIndex == 0) {          // 把第1列第0行和第2列第0行的单元格隐去          return { display: "none" };        }      }      if ((columnIndex == 0) & (rowIndex == 0)) {        // 把第0列第0行的单元格横向延长,补上刚刚隐去的单元格地位,并上个色        this.$nextTick(() => {          document.querySelector(`.${column.id}`).setAttribute("colspan", "3");        });        return { background: "pink" };      }      /**       * 合并:重要信息--->公开重要信息--->喜好性情单元格 【通过单元格的文字内容来合并】       * */      if (column.label == "性情") {        return { display: "none" };      }      if (column.label == "喜好&性情") {        this.$nextTick(() => {          document.querySelector(`.${column.id}`).setAttribute("colspan", "2");        });        return { background: "orange" }; // 不加这个也行,加了只是为了更好辨别      }      /**       * 重要!重要!重要!       *    咱们想要合并表头的单元格,须要先找到对应单元格       *    能够通过列column对象的label或者行与列索引来找到,找到当前进行暗藏或合并       *    也能够遍历行row数组找,不过会麻烦一些,集体倡议通过column来找       * */      // 通过column找      if (column.label == "技能") {        return { background: "#baf" };      }      // 通过row找      for (const item of row) {        if (item.label == "重要信息") {          this.$nextTick(() => {            document.querySelector(`.${item.id}`).style.background = "#ea66a6";          });          break;        }      }    },  },};</script>
  • 还能够,间接通过column.label找到对应单元格,而后进行合并单元格操作,不应用rowIndex和columnIndex了
  • 这种形式,在某些状况下,会更加不便
  • 但无论哪种形式,实质思路都是先找到单元格,再进行合并相干操作
headerCellStyle({ row, column, rowIndex, columnIndex }) {  // 第一局部的合并  if (column.label == "年龄") {    return { display: "none" };  }  if (column.label == "他乡") {    return { display: "none" };  }  if (column.label == "根本信息(姓名、年龄、他乡)") {    this.$nextTick(() => {      document.querySelector(`.${column.id}`).setAttribute("colspan", "3");    });    return { background: "pink" };  }  // 第二局部的合并  if (column.label == "性情") {    return { display: "none" };  }  if (column.label == "喜好&性情") {    this.$nextTick(() => {      document.querySelector(`.${column.id}`).setAttribute("colspan", "2");    });    return { background: "orange" };  }},

总结

读到这里,大家对表头合并相干问题应该都能应答了,若是还有不能应答的,能够发到评论区,大家一块帮忙解决

A good memory is better than a bad pen. Write it down...